Нажмите и перетащите jlabel на jcomponent в java

Я пытаюсь добавить JLabel в JComponent (который уже находится на JPanel), а затем сделать так, чтобы я мог щелкнуть и перетащить JLabel, чтобы переместить его в другое место.

На данный момент JLabel действительно появляется, но когда я щелкаю и перетаскиваю его, он перемещает весь JComponent, а не только JLabel сам по себе.

Вот пример кода:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.imageio.ImageIO;
import java.io.*;

public class Test extends JComponent implements ActionListener {
    int dragX, dragY;
    public void paintComponent(Graphics g) {

        Graphics2D g2 = (Graphics2D) g;
        g2.drawRect(0, 0, 300, 300);

        MouseListener ml = new MouseListener() {
            public void mousePressed(MouseEvent e) { 
                dragX = e.getX();
                dragY = e.getY();
            }
        };

        MouseMotionAdapter mma = new MouseMotionAdapter() {
            public void mouseDragged(MouseEvent e){
                setLocation(e.getX() - dragX + getLocation().x,
                        e.getY() - dragY + getLocation().y);
            }
        };

        BufferedImage image;
        try {
            image = ImageIO.read(new File("image.png"));
            ImageIcon i = new ImageIcon(image);
            JLabel label = new JLabel(i);                                               
            label.setBounds(30, 30, 60, 19);
            label.addMouseListener(ml);
            label.addMouseMotionListener(mma);
            add(label);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(900, 650);
        frame.setVisible(true);
        frame.setResizable(false);
        Test t = new Test();
        frame.getContentPane().add(t);
    }
}

Я чувствую, что это как-то связано со строкой setLocation() в блоке MouseMotionAdapter(), но я не совсем уверен.

Заранее спасибо!


person Seb    schedule 22.02.2016    source источник
comment
Рассмотрите возможность использования JLayeredPane или даже стеклянной панели, чтобы помочь вам перемещать метку. Например.   -  person Hovercraft Full Of Eels    schedule 23.02.2016
comment
Ну, во-первых, не делайте все это в методе paintComponent, это только вызовет проблемы   -  person MadProgrammer    schedule 23.02.2016
comment
Или этот пример может быть даже лучше.   -  person Hovercraft Full Of Eels    schedule 23.02.2016
comment
О боже, я не знал, что вы делаете все это в PaintComponent, включая создание и добавление MouseListeners, чтение файлов изображений, создание и размещение компонентов. Пожалуйста, поймите, что заявление @MadProgrammer было грубым преуменьшением, что выполнение подобных вещей внутри paintComponent не вызывает проблем, это напрашивается на полную катастрофу. Просто используйте paintComponent только для рисования и рисования, и не забудьте вызвать PaintComponent super в своем переопределении.   -  person Hovercraft Full Of Eels    schedule 23.02.2016
comment
Не уверен, почему все используют JLayeredPane или GlassPane для перетаскивания метки. В любом случае метка в конечном итоге должна быть расположена на JPanel, так почему бы просто не перетащить ее по панели? Просто используйте нулевой макет на своей панели, и вы можете использовать DragListener, содержащийся в Пример переноса Windows. Это в основном код, который у вас есть сейчас, за исключением того, что логика находится в отдельном классе. Я, конечно, не рекомендовал бы ответ, предложенный как дубликат.   -  person camickr    schedule 23.02.2016