Java拖放和鼠标监听器

4
我在使用触摸界面时,采用以下逻辑。因此,我想能够使用mousePressed来启动拖动功能,同时如果用户没有拖动,也可以使用mouseClicked或mouseReleased。
当鼠标按下时,我开始拖动。当鼠标被单击时,我希望它打印出“mouseClicked”,并在“mouseReleased”上打印mouseReleased,但由于某种原因,...
    dropLabel.getTransferHandler().exportAsDrag(dropLabel, e,
            TransferHandler.COPY);

吞噬了事件导致鼠标点击和释放事件即使我没有移动鼠标也不会被触发。请注意,注释掉那行代码会导致所有的监听器都被触发(但显然拖动并没有开始)。如何让我想要的所有鼠标事件发生,特别是当用户不做任何拖动时 mouseClicked/mouseReleased,同时仍能够在用户拖动时导出为拖动项?任何黑客/破解/反射方案都可以。

以下是我正在使用的一些示例代码,说明了我的实际问题:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.TransferHandler;

public class DragTest extends JFrame implements MouseMotionListener,
        MouseListener {

    private JPanel leftPanel = new JPanel(null);
    private JPanel rightPanel = new JPanel(null);
    JLabel dropLabel;

    public DragTest() {
        this.setLayout(new GridLayout(1, 2));

        leftPanel.setBorder(BorderFactory.createLineBorder(Color.black));
        rightPanel.setBorder(BorderFactory.createLineBorder(Color.black));
        this.add(leftPanel);
        this.add(rightPanel);
        leftPanel.addMouseListener(this);
        leftPanel.addMouseMotionListener(this);

        JTextArea area = new JTextArea();

        rightPanel.setLayout(new GridLayout(1, 1));
        rightPanel.add(area);

        dropLabel = new JLabel("drop");
        dropLabel.setTransferHandler(new TransferHandler("text"));

    }

    @Override
    public void mousePressed(MouseEvent e) {
        System.out.println("mousePressed");


        Dimension labelSize = dropLabel.getPreferredSize();
        dropLabel.setSize(labelSize);
        int x = e.getX() - labelSize.width / 2;
        int y = e.getY() - labelSize.height / 2;
        dropLabel.setLocation(x, y);
        leftPanel.add(dropLabel);


        dropLabel.getTransferHandler().exportAsDrag(dropLabel, e,
                TransferHandler.COPY);

        repaint();

    }

    @Override
    public void mouseDragged(MouseEvent me) {
        System.out.println("mouseDragged");
    }

    @Override
    public void mouseMoved(MouseEvent e) {

    }

    @Override
    public void mouseClicked(MouseEvent e) {
        System.out.println("mouseClicked");
    }

    @Override
    public void mouseReleased(MouseEvent e) {

        System.out.println("mouseReleased");

    }

    @Override
    public void mouseEntered(MouseEvent e) {

    }

    @Override
    public void mouseExited(MouseEvent e) {

    }

    public static void main(String[] args) {

        DragTest frame = new DragTest();
        frame.setVisible(true);
        frame.setSize(600, 400);
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

根据定义,mouseClicked事件只会在鼠标按下和释放的同一点发生。请尝试改用mouseReleased。您可能不应该在单击事件上安装传输处理程序,而应将其作为正常初始化过程的一部分建立。 - MadProgrammer
同意 - 但是mouseReleased也没有被调用。我根据您的一些反馈更新了代码。 - mainstringargs
我不会使用TransferHandler API :P - MadProgrammer
2个回答

8

你真的需要mouseReleased事件触发吗?我认为这个应该能很好地工作:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.TransferHandler;

public class DragTest extends JFrame implements MouseMotionListener,
        MouseListener {

    private JPanel leftPanel = new JPanel(null);
    private JPanel rightPanel = new JPanel(null);
    JLabel dropLabel;

    public DragTest() {
        this.setLayout(new GridLayout(1, 2));

        leftPanel.setBorder(BorderFactory.createLineBorder(Color.black));
        rightPanel.setBorder(BorderFactory.createLineBorder(Color.black));
        this.add(leftPanel);
        this.add(rightPanel);
        leftPanel.addMouseListener(this);
        leftPanel.addMouseMotionListener(this);

        JTextArea area = new JTextArea();

        rightPanel.setLayout(new GridLayout(1, 1));
        rightPanel.add(area);

        dropLabel = new JLabel("drop");
        dropLabel.setTransferHandler(new TransferHandler("text"));

    }
    @Override
    public void mousePressed(MouseEvent e) {
        System.out.println("mousePressed");
        Dimension labelSize = dropLabel.getPreferredSize();
        dropLabel.setSize(labelSize);
        int x = e.getX() - labelSize.width / 2;
        int y = e.getY() - labelSize.height / 2;
        dropLabel.setLocation(x, y);
        leftPanel.add(dropLabel);



        repaint();

    }

    @Override
    public void mouseDragged(MouseEvent me) {
        System.out.println("mouseDragged");
            dropLabel.getTransferHandler().exportAsDrag(dropLabel, me,
                    TransferHandler.COPY);
    }

    @Override
    public void mouseMoved(MouseEvent e) {
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        System.out.println("mouseClicked");
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        System.out.println("mouseReleased");

    }

    @Override
    public void mouseEntered(MouseEvent e) {

    }

    @Override
    public void mouseExited(MouseEvent e) {

    }

    public static void main(String[] args) {

        DragTest frame = new DragTest();
        frame.setVisible(true);
        frame.setSize(600, 400);
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

我将开始拖动事件的调用移动到了mouseDragged调用中,这样如果你只是单击鼠标,那么一切都会正常调用。然而,如果你拖动鼠标,它将触发拖放调用,它仍然会阻塞其他调用,但只有在你拖动时才会阻塞。如果你只是单击,所有内容都会正常调用。


-2
    @Override
    public void mouseDragged(MouseEvent e) {
        System.out.println(String.format("[mouseDragged] (%d, %d)", e.getX(),e.getY()));
        Dimension labelSize = dropLabel.getPreferredSize();
        dropLabel.setSize(labelSize);
        int x = e.getX() - labelSize.width / 2;
        int y = e.getY() - labelSize.height / 2;
        dropLabel.setLocation(x, y);
        leftPanel.add(dropLabel);

        repaint();
    }

鼠标事件..??


请在您的回答中加入一些上下文,并解释您的答案如何解决实际问题。 - Prakash Boda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接