Проблема с расширением класса 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

У меня есть несколько вопросов:

  1. Почему e. getY () принимает отрицательные результаты?

  2. Когда я перетаскиваю свою метку, появляется копия метки, которая тянется рядом с моей меткой. Как я могу это исправить?

  3. Когда я тащу свой этикетка, она тянется очень медленно.Например: когда я перемещаю курсор на 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 2

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);
    }
}