Проблема с расширением класса JLabel для добавления в него свойства перетаскивания
У меня есть класс JLabelExtended, который расширяет класс javax.качать.Метка 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
У меня есть несколько вопросов:
-
Почему e. getY () принимает отрицательные результаты?
-
Когда я перетаскиваю свою метку, появляется копия метки, которая тянется рядом с моей меткой. Как я могу это исправить?
-
Когда я тащу свой этикетка, она тянется очень медленно.Например: когда я перемещаю курсор на 10 точек, моя метка перемещается только на 5 точек. Как я могу это исправить?
Заранее спасибо
Вот еще один способ расширить JLabel:
Public class LabelEasy расширяет JLabel { частный 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);
}
}
Но он работает так же, как и предыдущий вариант.
1 ответ:
Я думаю, что ты делаешь это неправильно. MouseMotionListener добавляется к JLabel, и его расположение относительно JLabel, а не контейнера, в котором находится JLabel, поэтому информация бесполезна, чтобы помочь вам перетащить его. Вы можете использовать MouseAdapter и добавить его как MouseListener и MouseMotionListener. На mousePressed, получить расположение JLabel и мыши относительно экрана, а затем использовать его для перетаскивания на mousedraged. Сам я бы не стал распространяться. JLabel, чтобы сделать это, но предпочел бы просто использовать обычный JLabel, но это мое предпочтение.
Edit: это сработало лучше для меня, когда я имел дело с положением мыши относительно экрана (вызывая 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); } }