Java 拖放和鼠标侦听器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17245119/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-01 01:26:29  来源:igfitidea点击:

Java Drag and Drop and Mouse Listeners

javadrag-and-dropmouseeventmouselistener

提问by mainstringargs

I am using logic like the following with a touch interface, so I'd like to be able to use mousePressed to initiate a drag, yet at the same time be able to use mouseClicked or mouseReleased if the user does not drag.

我在触摸界面上使用如下逻辑,所以我希望能够使用 mousePressed 来启动拖动,但同时如果用户不拖动,则能够使用 mouseClicked 或 mouseReleased 。

On mousePressed, I have a drag being started. On mouseClicked, I want it to print out "mouseClicked", and to print mouseReleased on "mouseReleased" but for some reason the

在 mousePressed 上,我开始拖动。在 mouseClicked 上,我希望它打印出“mouseClicked”,并在“mouseReleased”上打印 mouseReleased 但由于某种原因

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

swallows the event causing mouseClicked and mouseReleased events not be fired even when I don't move the mouse. Notice that commenting out that line causes all listeners to be fired (but obviously the drag isn't started).

吞下导致 mouseClicked 和 mouseReleased 事件的事件,即使我不移动鼠标也不会触发。请注意,注释掉该行会导致所有侦听器被触发(但显然拖动并未开始)。

How can I get all mouse events to happen the way I want, specifically mouseClicked/mouseReleased when the user doesn't do any dragging, while still being able to exportAsDragged if the user does drag? Any hacks/cracks/reflection solutions are welcome.

我怎样才能让所有鼠标事件按照我想要的方式发生,特别是当用户不进行任何拖动时 mouseClicked/mouseReleased,同时如果用户确实拖动,仍然能够 exportAsDragged ?欢迎任何黑客/裂缝/反射解决方案。

Here is some sample code I am working with that illustrates my actual problem:

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

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

回答by Alex Coleman

Do you really need the mouseReleased to fire or what? I think this should work well:

你真的需要 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);
    }
}

I just moved the call to start the drag event into the mouseDragged call, this way if you just click your mouse then everything calls normally. However, if you drag the mouse, it will fire the drag and drop call, which still does block other calls, but again only if you drag. If you just click, it all fires normally.

我只是将启动拖动事件的调用移到 mouseDragged 调用中,这样如果您只需单击鼠标,那么一切都会正常调用。但是,如果您拖动鼠标,它会触发拖放调用,这仍然会阻止其他调用,但只有在您拖动时才会再次调用。如果你只是点击,它会正常触发。