JLabel使用鼠标运动监听器无法正常移动,为什么?

时间:2014-10-15 05:43:34

标签: java swing

每当我拖动鼠标时,我都需要相应地移动JLabel 为什么在拖动时显示多个JLabel并且没有在适当的位置显示组件?

public class Mover extends JFrame 
{

private JPanel jPanel;
private JLabel jLabel1;
private JLabel jLabel2;
private int myXX = 0;
private int myYY = 0;

public Mover() {
    setSize(500, 500);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    jPanel = new JPanel(null);
    jLabel1 = new JLabel("label one");
    jLabel2 = new JLabel("label two");

    jLabel1.setBounds(100, 100, 100, 100);
    jLabel2.setBounds(100, 100, 100, 100);
    jLabel1.addMouseMotionListener(new MouseMotionListener() {

        @Override
        public void mouseMoved(MouseEvent e) {
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            System.out.println("Label One");
            myXX = e.getX() - (jLabel1.getWidth() / 2);
            myYY = e.getY() - (jLabel1.getHeight() / 2);
            jLabel1.setLocation(myXX, myYY);
            repaint();
        }
    });
    jLabel2.addMouseMotionListener(new MouseMotionListener() {

        @Override
        public void mouseMoved(MouseEvent e) {
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            System.out.println("Label Two");

            myXX = e.getX() - (jLabel2.getWidth() / 2);
            myYY = e.getY() - (jLabel2.getHeight() / 2);
            jLabel2.setLocation(myXX, myYY);
            repaint();
        }
    });
    jPanel.add(jLabel1);
    jPanel.add(jLabel2);
    add(jPanel);
    repaint();
    revalidate();
    setVisible(true);
}

public static void main(String args[]) {
    new Mover();
}
}

这个问题是否有任何解决方案? 显然在此先感谢。

1 个答案:

答案 0 :(得分:2)

MouseEvent信息与生成事件的组件(在本例中为标签)具有上下文关系。

这意味着0x0实际上是标签的左上角。您需要将事件的点信息转换为它的父上下文,例如......

Point p = e.getPoint();
p = SwingUtilities.convertPoint(e.getComponent(), p, e.getComponent().getParent());

您也不需要制作myXXmyYY个实例字段,因为它们实际上只有正在驱动它们的鼠标事件的上下文。

您还应该查看Initial Threads并确保您在事件调度线程的上下文中启动您的程序...

您也不需要为每个组件创建单独的侦听器,只需稍加巧妙地使用MouseEvent中的可用信息,您就可以为所有组件使用单个侦听器减少代码重复......

import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Mover extends JFrame {

    private JPanel jPanel;
    private JLabel jLabel1;
    private JLabel jLabel2;

    public Mover() {
        setSize(500, 500);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        jPanel = new JPanel(null);
        jLabel1 = new JLabel("label one");
        jLabel2 = new JLabel("label two");

        jLabel1.setBounds(100, 100, 100, 100);
        jLabel2.setBounds(100, 100, 100, 100);

        MouseMotionListener mover = new MouseMotionListener() {

            @Override
            public void mouseMoved(MouseEvent e) {
            }

            @Override
            public void mouseDragged(MouseEvent e) {
                System.out.println("Label One");

                Component child = e.getComponent();
                Point p = e.getPoint();
                p = SwingUtilities.convertPoint(e.getComponent(), p, e.getComponent().getParent());

                int myXX = p.x - (child.getWidth() / 2);
                int myYY = p.y - (child.getHeight() / 2);
                child.setLocation(myXX, myYY);
                repaint();
            }
        };

        jLabel1.addMouseMotionListener(mover);
        jLabel2.addMouseMotionListener(mover);

        jPanel.add(jLabel1);
        jPanel.add(jLabel2);
        add(jPanel);
        setVisible(true);
    }

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                new Mover();
            }
        });
    }
}

如果我没有指出直接从像JFrame这样的顶级容器扩展是不好的做法并且会将你锁定在一个单独的容器中,我会对你造成伤害。如果你愿意的话,将来很难重新使用容器或将其添加到其他容器中......此外,你并没有真正添加任何功能......

相关问题