【问题标题】:MouseEvent on JPanel - wrong coordinateJPanel 上的 MouseEvent - 坐标错误
【发布时间】:2012-08-27 06:57:02
【问题描述】:

我用Java编写了以下微型画笔程序:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;


class AuxClass1 extends JFrame implements MouseListener, MouseMotionListener{

    private JPanel panel1 = new JPanel();
    private JPanel panel2 = new JPanel();
    private JLabel label1_x = new JLabel();
    private JLabel label1_y = new JLabel();
    private JLabel label1_x_info = new JLabel("");
    private JLabel label1_y_info = new JLabel("");
    //add a container keep panels with widgets 
    private Container con1 = getContentPane();

    private int xval1;
    private int yval1;

    private GridLayout layout1 = new GridLayout(2,2,2,2);

    private JOptionPane info1 = new JOptionPane();

    //get the class that controls the mouse
    public AuxClass1(){
        super("Mouse Experiment");
        panel1.setBackground(Color.WHITE);      
        panel1.setLayout(layout1);
        label1_x.setText("X Location");
        label1_x.setBorder(BorderFactory.createLineBorder(Color.BLUE, 2));
        label1_y.setBorder(BorderFactory.createLineBorder(Color.BLUE, 2));
        label1_x_info.setBorder(BorderFactory.createLineBorder(Color.RED, 2));
        label1_y_info.setBorder(BorderFactory.createLineBorder(Color.RED, 2));
        label1_y.setText("Y Location");     
        panel1.add(label1_x);
        panel1.add(label1_y);
        panel1.add(label1_x_info);
        panel1.add(label1_y_info);
        con1.add(panel1, BorderLayout.NORTH);
        panel2.setBackground(new Color(100,200,200));
        panel2.setBorder(BorderFactory.createLineBorder(new Color(255,255,0), 2));
        panel2.addMouseListener(this);
        panel2.addMouseMotionListener(this);
        con1.add(panel2, BorderLayout.CENTER);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(500, 500);
        setLocationRelativeTo(null);
        setVisible(true);


    }

    @Override
    public void mouseClicked(MouseEvent arg0) {


    }

    @Override
    public void mouseMoved(MouseEvent arg0) {
        // TODO Auto-generated method stub
        if (arg0.getSource()==panel2){
            x_var = arg0.getX();
            y_var = arg0.getY();
            label1_x_info.setText(Integer.toString(x_var));
            label1_y_info.setText(Integer.toString(y_var));
        }

    }

    @Override
    public void mouseDragged(MouseEvent e) {
        // TODO Auto-generated method stub
        if (e.getSource()==panel2){
            //info1.showMessageDialog(this, "This is an awesome Mouse toolbox!");
            xval1 = e.getX();
            yval1= e.getY();
            AuxClass2 Inst2 = new AuxClass2(xval1, yval1);
            Inst2.paintComponent(getGraphics());
            }

    }

    @Override
    public void mouseEntered(MouseEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseExited(MouseEvent arg0) {
        if (arg0.getSource()==panel2){
            label1_x_info.setText("");
            label1_y_info.setText("");
        }
        // TODO Auto-generated method stub

    }

    @Override
    public void mousePressed(MouseEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseReleased(MouseEvent arg0) {
        // TODO Auto-generated method stub

    }


}

class AuxClass2 extends JPanel{

    //JOptionPane info2 = new JOptionPane();
    private int xval2;
    private int yval2;

    public AuxClass2(int input1, int input2){

        xval2 = input1;
        yval2 = input2;
        setSize(500,500);

    }

    @Override
    public void paintComponent(Graphics g){
        super.paintComponents(g);
        g.setColor(Color.BLUE);
        g.fillRect(xval2, yval2+70, 5, 5);  

    }

}

public class MainClass{

    private static AuxClass1 Inst1;

    public static void main(String args[]){

        Inst1 = new AuxClass1();


    }

}

除了 mouseDragged 方法的 Y 坐标外,它工作正常(参见 t3_aux2 类中的 paintComponent 方法)。由于某种原因,该方法使用的 Y 坐标比 panel2 中的实际 Y 坐标小约 70 像素。我怀疑这与 t3_aux2 类中继承的 JPanel 方法有关,但不太确定。

如果有人能澄清这一点,那就太酷了。谢谢。

UPD:如果有人对如何改进样式和/或优化代码有任何建议,我们也将不胜感激。

UPD2:更改了名称以符合 Java 命名约定。

【问题讨论】:

  • 没有看你的问题,只是看你的代码:a)永远不要使用getGraphics b)不要调用paintComponent,而是调用repaint c)请学习java命名约定并遵守它们
  • 我同意 c),我是 Java 新手。请您更具体地了解 a) 和 b)。我遵循了我在各种 Java 教程中找到的风格和方法,包括 Oracle 网站上的那个。
  • cool - 如何编辑您的问题以包括遵循您迄今为止所学的约定 :-) 至于其他点,请查看 swing tag wiki - 有一些参考必须-已经阅读。
  • 我添加了更新。我会看看摇摆标签的结果。如果您至少可以评论从不使用getGraphics() ,那将是非常酷的。
  • 当您调用repaint() 时,该组件将被安排重新绘制。 Swing 将自动调用paint() 或paintComponent(),并在参数中使用适当的Graphics 对象。

标签: java swing awt jpanel mouseevent


【解决方案1】:

我试过你的代码。我认为您的问题来自您使用 t3_aux2 坐标在 t3_aux1 上绘画的事实。我会尝试确认一下,然后我会回到这里......

编辑:好的,就是这样。

在t3_aux1构造函数中,如果你写

System.out.println("panel1 height = " + panel1.getHeight());
System.out.println("label1 height = " + label1_x.getHeight())

打印出来

panel1 height = 42
label1 height = 20

所以你的偏移量是 42 + 20 + 4*2 = 70

4*2 来自您的线条边框,粗细为 2。

由于可以计算出精确的偏移量,因此您可以动态修复它。

编辑 2:

实际上,您使用的坐标来自 panel2,因为 mouseListener 已附加到 panel2。但是您在 JFrame 图形上绘图,而不是在 panel2 图形上。

写这个应该可以解决你的坐标问题。

inst2.paintComponent(panel2.getGraphics());

但正如 Kleopatra 所说,你的做法不对。你永远不应该打电话给getGraphics() 或paintComponent()。我认为您应该考虑使用java.awt.Canvas 作为“panel2”对象的超类。

另外一个建议:请注意,您的绘图不会被记住,因此,如果您缩小窗口或将其隐藏在另一个窗口后面,所有绘制的内容都会丢失。

【讨论】:

  • 谢谢,你能解释一下“动态修复”的意思吗?
  • 我的意思是你不应该使用 70 来固定偏移量,而是你应该计算这个值,然后如果你修改一些东西(例如线条边框粗细),偏移量将保持固定.不过我正在为您准备一点代码改进,等我有时间完成时再发布。
  • 我猜你正在尝试制作井字游戏?我不明白为什么每次要绘制时都要实例化一个新对象?
  • 您的意思是 mouseDragged 方法中的inst2?我不知道有什么更好的方法。你有什么建议吗?
  • 是的,在mouseDragged 方法中,您可以简单地执行getGraphics().fillRect(...) 之类的操作,而不是创建新对象。但是,这又不是最好的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-27
  • 1970-01-01
  • 2012-04-30
相关资源
最近更新 更多