JavaFX:如何检测屏幕上任何位置的 mouse/key 事件?

JavaFX: How to detect mouse/key events anywhere on screen?

我正在尝试在 Java(fx) 中捕获 mouse/key 事件,即使 应用程序 window 没有专注... 我正在创建类似屏幕录像机的东西,我想通过按 "F9" 等键来停止录制,因此我需要检测该事件。这可能吗? 我可以使用 系统侦听器 之类的东西吗?

~亨利

很遗憾,您不能这样做。 JavaFX 需要专注 window。使用 Java 没有简单的方法来实现您想要的,因为出于安全目的,它几乎无法控制 OS。最好的办法是编写一个 C 应用程序来执行此操作,然后使用 JNI 从 Java 连接到它。

你会想做两件事。

  1. 编写一个 C 程序来侦听 OS 上的全局事件。对于 Windows,您可以在 MSDN 上找到更多相关信息,对于 mac 和 linux,您将需要使用 X11 库。

  2. 使用 JNI 来 link 您在 Java 中的 C 代码。这并不像听起来那么难,这里有一个很好的教程:https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html

当然,您不必自己完成所有工作,几乎所有内容都有库。这个库为你做了艰苦的工作,你可以用它来实现你的目标:https://github.com/kwhat/jnativehook

这是可能的,但标准 Java 如果注册的组件未处于焦点,则无法访问击键或鼠标事件。

为了实现这一点,您需要通过 Java 本机接口 (JNI) 使用本机代码。这使得 Java 代码能够调用本机应用程序(特定于硬件和操作系统平台的程序)和用其他语言(例如 C 和 C++)编写的库。

幸运的是,有一个第三方库 JNativeHook 专为您的需要而设计。您可以在这里找到它:https://github.com/kwhat/jnativehook

如果您使用 Maven 进行依赖管理,您可以轻松安装它。这是一个工作示例:

App.java

package com.sotest.globalkeylistener;

import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;

public class App 
{
    public static void main(String[] args) {
        try {
            GlobalScreen.registerNativeHook();
        }
        catch (NativeHookException ex) {
            System.exit(1);
        }

        GlobalScreen.addNativeKeyListener(new GlobalKeyListener());
    }
}

GlobalKeyListener.java

package com.sotest.globalkeylistener;

import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.keyboard.NativeKeyEvent;
import org.jnativehook.keyboard.NativeKeyListener;

public class GlobalKeyListener implements NativeKeyListener {

    public void nativeKeyPressed(NativeKeyEvent e) {
        System.out.println("Key Pressed: " + NativeKeyEvent.getKeyText(e.getKeyCode()));

        if (e.getKeyCode() == NativeKeyEvent.VC_ESCAPE) {
            try {
                GlobalScreen.unregisterNativeHook();
            } catch (NativeHookException e1) {
                e1.printStackTrace();
            }
        }
    }

    public void nativeKeyReleased(NativeKeyEvent e) {
        System.out.println("Key Released: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
    }

    public void nativeKeyTyped(NativeKeyEvent e) {
        System.out.println("Key Typed: " + e.getKeyText(e.getKeyCode()));
    }
}

关键输出:

鼠标输出

这样即使您的 Java 应用程序被最小化,您也可以检测到事件。

希望对您有所帮助。