Java 鼠标在屏幕上的任何位置移动

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2469515/
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-10-29 21:20:02  来源:igfitidea点击:

Java mouse motion anywhere on screen

javaswingmouseevent

提问by Dave

I'm sure this is possible but all my searching is coming up blank.

我确信这是可能的,但我所有的搜索都是空白的。

In Java is it possible to register for a mouse motion event outside of a Java app? So if the mouse pointer moves anywhere on the screen I get a call back. An approximation is possible with polling MouseInfo.getPointerInfobut there must be a better way.

在 Java 中是否可以在 Java 应用程序之外注册鼠标移动事件?因此,如果鼠标指针在屏幕上的任何位置移动,我就会收到回电。轮询可以进行近似,MouseInfo.getPointerInfo但必须有更好的方法。

Thanks

谢谢

To explain the use case: It's just for a pet project but basically firing events when the mouse hits the edge of the screen. I was also thinking that different events could be fired if you try to push pastthe edge of the screen. And for this I thought a mouse motion listener might be more appropriate.

解释用例:它只是一个宠物项目,但基本上是在鼠标点击屏幕边缘时触发事件。我还认为,如果您尝试越过屏幕边缘,可能会触发不同的事件。为此,我认为鼠标运动侦听器可能更合适。

回答by Thomas

java.awt.event.MouseMotionListeneris only going to give you information about mouse movement inside your application window. For events that occur outside that window, there is no way around MouseInfo.getPointerInfo. However, you could write a (potentially singleton) class that polls the pointer info in regular intervals and allows MouseMotionListenersto be added:

java.awt.event.MouseMotionListener只会为您提供有关应用程序窗口内鼠标移动的信息。对于发生在该窗口之外的事件,没有办法绕过MouseInfo.getPointerInfo。但是,您可以编写一个(可能是单例)类,它定期轮询指针信息并允许MouseMotionListeners添加:

import java.awt.Component;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.HashSet;
import java.util.Set;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

/**
 * This class checks the position every #DELAY milliseconds and 
 * informs all registered MouseMotionListeners about position updates.
 */
public class MouseObserver {
    /* the resolution of the mouse motion */
    private static final int DELAY = 10;

    private Component component;
    private Timer timer;
    private Set<MouseMotionListener> mouseMotionListeners;

    protected MouseObserver(Component component) {
        if (component == null) {
            throw new IllegalArgumentException("Null component not allowed.");
        }

        this.component = component;

        /* poll mouse coordinates at the given rate */
        timer = new Timer(DELAY, new ActionListener() {
                private Point lastPoint = MouseInfo.getPointerInfo().getLocation();

                /* called every DELAY milliseconds to fetch the
                 * current mouse coordinates */
                public synchronized void actionPerformed(ActionEvent e) {
                    Point point = MouseInfo.getPointerInfo().getLocation();

                    if (!point.equals(lastPoint)) {
                        fireMouseMotionEvent(point);
                    }

                    lastPoint = point;
                }
            });
        mouseMotionListeners = new HashSet<MouseMotionListener>();
    }

    public Component getComponent() {
        return component;
    }

    public void start() {
        timer.start();
    }

    public void stop() {
        timer.stop();
    }

    public void addMouseMotionListener(MouseMotionListener listener) {
        synchronized (mouseMotionListeners) {
            mouseMotionListeners.add(listener);
        }
    }

    public void removeMouseMotionListener(MouseMotionListener listener) {
        synchronized (mouseMotionListeners) {
            mouseMotionListeners.remove(listener);
        }
    }

    protected void fireMouseMotionEvent(Point point) {
        synchronized (mouseMotionListeners) {
            for (final MouseMotionListener listener : mouseMotionListeners) {
                final MouseEvent event =
                    new MouseEvent(component, MouseEvent.MOUSE_MOVED, System.currentTimeMillis(),
                                   0, point.x, point.y, 0, false);

                SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                            listener.mouseMoved(event);
                        }
                    });
            }
        }
    }

    /* Testing the ovserver */
    public static void main(String[] args) {
        JFrame main = new JFrame("dummy...");
        main.setSize(100,100);
        main.setVisible(true);

        MouseObserver mo = new MouseObserver(main);
        mo.addMouseMotionListener(new MouseMotionListener() {
                public void mouseMoved(MouseEvent e) {
                    System.out.println("mouse moved: " + e.getPoint());
                }

                public void mouseDragged(MouseEvent e) {
                    System.out.println("mouse dragged: " + e.getPoint());
                }
            });

        mo.start();
    }
}

Beware that there are some notable differences from your standard MouseMotionListener though:

请注意,尽管与标准 MouseMotionListener 存在一些显着差异:

  • You will only receive mouseMovedevents, never mouseDraggedevents. That's because there is no way to receive information about clicks outside the main window.
  • For similar reasons, the modifiersof each MouseEventwill be always be 0.
  • The same goes for the values clickCount, popupTrigger, button
  • You will need to provide a dummy java.awt.Componentthat will be used as the (fake) source of the MouseEvents - nullvalues are not allowed here.
  • 您只会收到mouseMoved事件,而不会收到mouseDragged事件。这是因为无法接收有关主窗口外点击的信息。
  • 出于类似的原因,modifiers每个的MouseEvent将始终为 0。
  • clickCount, popupTrigger, , 也是如此button
  • 您需要提供一个java.awt.Component将用作MouseEvents的(假)来源的虚拟对象-null此处不允许使用值。