События мыши JLabel для перетаскивания

Я хочу включить функцию перетаскивания над JLabel, переопределив события мыши над ней, но когда я определяю перетаскивание события mousePressed, mouseReleased не влияет на эту JLabel. Я что-то делаю неправильно?

            Thumbnails[I_Loop].setText("1");
            Thumbnails[I_Loop].setTransferHandler(new TransferHandler("text"));
            Thumbnails[I_Loop].addMouseListener( new MouseAdapter() {
                public void  mouseReleased(MouseEvent me) {
                       System.out.println("here mouse released");
                  }
                public void mousePressed(MouseEvent me) {
                    System.out.println("here mouse pressed");
                    JComponent comp = (JComponent) me.getSource();
                    TransferHandler handler = comp.getTransferHandler();
                    handler.exportAsDrag(comp, me, TransferHandler.COPY);
            });

* Эскизы - это массив JLabel

При запуске программы выполняется перетаскивание, но утверждение "здесь мышь выпущено" не печатается. Однако, когда я удаляю код, ответственный за DND, с помощью метода mousePressed(), выводится "здесь мышь выпущена".

Что не так в этом коде?

Ответ 1

Хорошо, если я правильно помню, механизм перетаскивания ловит все события мыши и обрабатывает их сам. Таким образом, обычные MouseEvents больше не выбрасываются. Вам нужно будет зарегистрировать DropTargetListener в JLabel DropTarget.

Ответ 2

@Томас правильный, но стоит отметить две альтернативы:

  • Этот пример показывает, как перетащить компонент с помощью JLayeredPane; этот вариант расширяет концепцию; этот более свежий пример использует аналогичный подход.

  • В приведенном ниже коде показано, как использовать MouseMotionListener; этот более сложный пример использует тот же принцип.

код:

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JFrame;
import javax.swing.JPanel;

/** @see https://stackoverflow.com/a/5312702/230513 */
public class MouseDragTest extends JPanel {

    private static final String TITLE = "Drag me!";
    private static final int W = 640;
    private static final int H = 480;
    private Point textPt = new Point(W / 2, H / 2);
    private Point mousePt;

    public MouseDragTest() {
        this.setFont(new Font("Serif", Font.ITALIC + Font.BOLD, 32));
        this.addMouseListener(new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent e) {
                mousePt = e.getPoint();
                repaint();
            }
        });
        this.addMouseMotionListener(new MouseMotionAdapter() {

            @Override
            public void mouseDragged(MouseEvent e) {
                int dx = e.getX() - mousePt.x;
                int dy = e.getY() - mousePt.y;
                textPt.setLocation(textPt.x + dx, textPt.y + dy);
                mousePt = e.getPoint();
                repaint();
            }
        });
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(W, H);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        int w2 = g.getFontMetrics().stringWidth(TITLE) / 2;
        g.drawString(TITLE, textPt.x - w2, textPt.y);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame f = new JFrame(TITLE);
                f.add(new MouseDragTest());
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.pack();
                f.setLocationRelativeTo(null);
                f.setVisible(true);
            }
        });
    }
}

Ответ 3

Должен ли быть JLabel? Я создал класс со строкой, которая могла бы начать работу.

import java.awt.Graphics;
import java.awt.MouseInfo;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;


public class mainProgram extends JPanel implements Runnable
{
    private static final long serialVersionUID = 1L;
    public static boolean MOUSE_DOWN = false;
    public static String str;

    public mainProgram() 
    {
        JFrame win = new JFrame("Window");

        win.add(this);

        win.setSize(700,500);
        win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        win.setVisible(true);
        str = "Drag me!";
        new Thread(this).start();
    }

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        if(MOUSE_DOWN)
        {
            g.drawString(str, MouseInfo.getPointerInfo().getLocation().x, MouseInfo.getPointerInfo().getLocation().y);
        }
    }

    @Override
    public void run() 
    {
        Thread t = Thread.currentThread();

        this.addMouseListener(new MouseListener()
        {

            @Override
            public void mouseClicked(MouseEvent arg0) 
            {

            }

            @Override
            public void mouseEntered(MouseEvent arg0) 
            {

            }

            @Override
            public void mouseExited(MouseEvent arg0) 
            {

            }

            @Override
            public void mousePressed(MouseEvent arg0) 
            {
                MOUSE_DOWN = true;
            }

            @Override
            public void mouseReleased(MouseEvent arg0) 
            {
                MOUSE_DOWN = false;
            }

        });

        while(t==Thread.currentThread())
        {
            if(MOUSE_DOWN)
                repaint();

            try {Thread.sleep(10);}
            catch (InterruptedException e) {e.printStackTrace();}
        }   
    }
}