【问题标题】:Is it possible to have a MouseMotionListener listen to all system mouse motion events?是否可以让 MouseMotionListener 监听所有系统鼠标运动事件?
【发布时间】:2010-10-05 00:14:19
【问题描述】:

我的样板听众:

class MyMouseMotionListener implements MouseMotionListener {
public void mouseDragged(MouseEvent e) {
    System.out.println("Dragged...");
}

public void mouseMoved(MouseEvent e) {
    System.out.println("Moved...");
}}

很简单,但是为了监听系统范围的事件,我应该添加什么?我一直在研究诸如 GraphicsDevice 和 AccessibleContext 子类之类的东西——它们不直接提供 MouseMotionListeners 的添加,但我希望它们能给我一些关于如何实现它的想法。

编辑:这根本不是基于事件的,但我发现了这个:

MouseInfo.getPointerInfo().getLocation()

即使应用程序本身没有焦点,它实际上也会在我的应用程序上下文之外返回鼠标位置。有什么方法可以观察到这一点并在其值发生变化时调度事件?

【问题讨论】:

  • 我不准备放弃仅使用 Java 提供的工具就可以实现这一点的想法。如 PointerInfo 类所示,鼠标位置(无论焦点如何)对于正在运行的 Java 进程是已知的。我现在正尝试将其正确呈现给我的应用以供使用。

标签: java swing awt


【解决方案1】:

您可以使用Toolkit.addAWTEventListener(AWTEventListener listener, long eventMask) 订阅 Java 容器层次结构中的所有鼠标事件。 eventMask 参数确定侦听器将接收哪些事件。

所以你的代码看起来像:

Toolkit.getDefaultToolkit().addAWTEventListener(new MyMouseMotionListener(), @987654322@);

【讨论】:

  • 这仅适用于您的 AWT/Swing 窗口。目前尚不清楚 OP 是否需要系统范围或 java 范围的事件。
  • 是的,你是对的,如果没有本机代码(甚至可能有它,但我不知道),监听所有系统事件是不可能的。这是下一个最好的事情。
  • 当我实现 AWTEventListener 作为我的鼠标移动监听器并使用 Toolkit 附加它时,它似乎具有完全相同的效果。使用任何一种方法,我仍然停留在应用程序本身的上下文中。还有其他想法吗?
  • 按照设计,Java 只能做主机操作系统允许它做的事情。这类事情需要本机代码来绕过 Java 的限制(而且它必须是特定于操作系统的代码)。恐怕没有其他办法了。
【解决方案2】:

更新:您可以轮询 MouseInfo 的位置,但您永远不会获得按钮状态。您将需要使用本机代码来获取按钮状态。

我认为不使用本机代码在应用程序的容器层次结构之外监听鼠标光标是不可能的。

【讨论】:

    【解决方案3】:

    我通过使用上述根据请求获取鼠标位置的功能解决了同样的问题。然后,我启动了一个新线程,在其余程序执行期间不断执行此操作。

    MouseInfo.getPointerInfo().getLocation()

    因此我不得不让主类扩展 Thread

    public class MouseMotion extends Thread {
    

    这要求您创建一个名为 run 的函数。 在你的 void 函数中简单地创建一个无限循环

    public void run() {
    int n=10;
    for (int i=0;i<n; n++) //horrible infinite loop
    {
        Thread.sleep(100); //this will slow the capture rate to 0.1 seconds
        PointerInfo a = MouseInfo.getPointerInfo();
        Point p = new Point (0,0);
        a = MouseInfo.getPointerInfo();
        p = a.getLocation();
        int x = (int)p.getX(); //getX and getY return doubles so typecast
        int y = (int)p.getY();
        System.out.println(""+x+"   "+y);   //to see it grabing locations not needed
    }
    }
    

    现在剩下的就是在您想要开始观察鼠标移动时调用线程。我在我的 main 之后立即启动线程

    public static main (String[] args) throws Exception {
    Thread thread = new MouseMotion();
    thread.start();
    ...}
    

    【讨论】:

    • 这不是无限循环。为什么不将“for”循环替换为:“while (true)”?
    【解决方案4】:

    如果您想监听/捕获系统上的所有鼠标事件(例如,不仅仅是您的应用程序窗口),您需要一个mouse hook

    【讨论】:

      【解决方案5】:

      为此有一些库,我经常将其中一个用于应用程序。

      JNativeHook 具有处理本地鼠标和键盘事件的非凡能力。 (google一下,我懒得去subversion了。虽然你可以下载这个库,它就像你两次调用库后的普通鼠标事件一样工作。

      我希望当我在谷歌上冲浪时,有人会在这样的线程上发布这个库。我一直在使用 stackoverflow,但我不是注册会员,因为我从不公开寻求帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-08-17
        • 2011-12-10
        • 2023-03-12
        • 2018-03-18
        • 2020-02-20
        • 2011-09-19
        • 2014-02-21
        • 2014-02-24
        相关资源
        最近更新 更多