2

我有 JLabelExtended 类,它扩展了 javax.swing.JLabel 类。我扩展它,因为我想使用鼠标添加属性拖动。这是我的代码:

public class JLabelExtended extends JLabel {
private MouseMotionAdapter mouseMotionAdapter;

private JLabelExtended jLabelExtended;

public LabelEasy(String text) {
    super(text);
    jLabelExtended = this;

    mouseMotionAdapter = new MouseMotionAdapter() {
        @Override
        public void mouseDragged(MouseEvent e) {
            System.out.println(e.getX() + "  :   " + e.getY());
            jLabelExtended.setLocation(e.getX(), e.getY()
            );
        }
    };

    jLabelExtended.addMouseMotionListener(mouseMotionAdapter);
}

}

这是标签拖动后的控制台部分:

163  :   163
144  :   -87
163  :   162
144  :   -88
163  :   161
144  :   -89

我有几个问题:

  1. 为什么 e.getY() 会产生负面结果?

  2. 当我拖动我的标签时,会出现在我的标签附近拖动的标签副本。我该如何解决?

  3. 当我拖动我的标签时,它拖得很慢。例如:当我将光标移动到 10 点时,我的标签只移动到 5 点。我该如何解决?

提前致谢

这是扩展 JLabel 的另一种方法:

公共类 LabelEasy 扩展 JLabel { private MouseAdapter moveMouseAdapter; 私有 MouseMotionAdapter mouseMotionAdapter;

private LabelEasy jLabelExtended;

private int xAdjustment, yAdjustment;
Boolean count = false;

public LabelEasy(String text) {
    super(text);
    jLabelExtended = this;

    moveMouseAdapter = new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
            if (e.getButton() == 1) {
                xAdjustment = e.getX();
                yAdjustment = e.getY();
            }
        }
    };

    mouseMotionAdapter = new MouseMotionAdapter() {
        @Override
        public void mouseDragged(MouseEvent e) {
            if (count) {
                System.out.println(e.getX() + "  :   " + e.getY());
                jLabelExtended.setLocation(xAdjustment + e.getX(), yAdjustment + e.getY());
                count = false;
            } else {
                count = true;
            }
            ;
        }
    };

    jLabelExtended.addMouseMotionListener(mouseMotionAdapter);
    jLabelExtended.addMouseListener(moveMouseAdapter);
}

}

但它像以前的变体一样工作。

4

1 回答 1

2

我认为你做错了。MouseMotionListener 被添加到 JLabel 并且它的位置是相对于 JLabel,而不是包含 JLabel 的 Container ,因此这些信息对于帮助您拖动它是无用的。您可能希望使用 MouseAdapter 并将其添加为 MouseListener 和 MouseMotionListener。在 mousePressed 上,获取 JLabel 和鼠标相对于屏幕的位置,然后将其用于在 mouseDragged 上进行拖动。我自己,我不会扩展 JLabel 来执行此操作,而是只使用常规的 JLabel,但这是我的偏好。

编辑:当我处理鼠标相对于屏幕的位置(通过调用 getLocationOnScreen)和 JLabel 相对于其容器的位置(通过调用 getLocation)时,它对我来说效果更好。例如,

import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;

public class DragLabelEg {
    private static final String[] LABEL_STRINGS = { "Do", "Re", "Me", "Fa",
            "So", "La", "Ti" };
    private static final int HEIGHT = 400;
    private static final int WIDTH = 600;
    private static final Dimension MAIN_PANEL_SIZE = new Dimension(WIDTH,
            HEIGHT);
    private static final int LBL_WIDTH = 60;
    private static final int LBL_HEIGHT = 40;
    private static final Dimension LABEL_SIZE = new Dimension(LBL_WIDTH,
            LBL_HEIGHT);
    private JPanel mainPanel = new JPanel();
    private Random random = new Random();

    public DragLabelEg() {
        mainPanel.setPreferredSize(MAIN_PANEL_SIZE);
        mainPanel.setLayout(null);

        MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
        for (int i = 0; i < LABEL_STRINGS.length; i++) {
            JLabel label = new JLabel(LABEL_STRINGS[i], SwingConstants.CENTER);
            label.setSize(LABEL_SIZE);
            label.setOpaque(true);
            label.setLocation(random.nextInt(WIDTH - LBL_WIDTH),
                    random.nextInt(HEIGHT - LBL_HEIGHT));
            label.setBackground(new Color(150 + random.nextInt(105),
                    150 + random.nextInt(105), 150 + random.nextInt(105)));
            label.addMouseListener(myMouseAdapter);
            label.addMouseMotionListener(myMouseAdapter);

            mainPanel.add(label);
        }
    }

    public JComponent getMainPanel() {
        return mainPanel;
    }

    private class MyMouseAdapter extends MouseAdapter {
        private Point initLabelLocation = null;
        private Point initMouseLocationOnScreen = null;

        @Override
        public void mousePressed(MouseEvent e) {
            JLabel label = (JLabel)e.getSource();
            // get label's initial location relative to its container
            initLabelLocation = label.getLocation();

            // get Mouse's initial location relative to the screen 
            initMouseLocationOnScreen = e.getLocationOnScreen();
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            initLabelLocation = null;
            initMouseLocationOnScreen = null;
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            // if not dragging a JLabel
            if (initLabelLocation == null || initMouseLocationOnScreen == null) {
                return;
            }
            JLabel label = (JLabel)e.getSource();

            // get mouse's new location relative to the screen
            Point mouseLocation = e.getLocationOnScreen();

            // and see how this differs from the initial location.
            int deltaX = mouseLocation.x - initMouseLocationOnScreen.x;
            int deltaY = mouseLocation.y - initMouseLocationOnScreen.y;

            // change label's position by the same difference, the "delta" vector
            int labelX = initLabelLocation.x + deltaX;
            int labelY = initLabelLocation.y + deltaY;

            label.setLocation(labelX, labelY);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createGui();
            }
        });
    }

    private static void createGui() {
        JFrame frame = new JFrame("App");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new DragLabelEg().getMainPanel());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
于 2011-02-21T22:20:39.657 回答