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

标签 java swing mouseevent

我确信这是可能的,但我所有的搜索都一无所获。

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

谢谢

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

最佳答案

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

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

  • 您只会收到 mouseMoved 事件,而不会收到 mouseDragged 事件。这是因为无法接收有关主窗口外点击的信息。
  • 出于类似的原因,每个 MouseEventmodifiers 将始终为 0。
  • 同样适用于值 clickCountpopupTriggerbutton
  • 您需要提供一个虚拟 java.awt.Component,它将用作 MouseEvent 的(假)源 - null 此处不允许使用值。

关于屏幕上任意位置的 Java 鼠标移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2469515/

相关文章:

java - SecureRandom 与 NativePRNG 对比 SHA1PRNG

java - 我应该在哪里保存 JDBC 连接详细信息?

java - 更新 JSlider Swing 的位置

vb.net - vb.net datagridview 中的长按事件是什么

jquery - 滚动和鼠标事件动画标题

java - 在 Swing 中未按下鼠标的组件上监听鼠标释放事件

java - 具有多个线程的Java中的对象指针

java - 带有 char 值的断言语句

用于创建图形的 Java 库

Javax 验证未捕获 POJO 的内部字段