我试图抓住Java(fx)中的鼠标/键事件,即使应用程序窗口未集中 ... 我正在创建类似于screenrecorder的东西,我想通过按“F9”之类的键来停止录制,所以我需要检测事件。这可能吗? 是否可以使用系统监听器?
〜亨利
答案 0 :(得分:5)
如果已注册的组件未处于焦点,则标准Java无法访问键击或鼠标事件。
为了实现这一目标,您需要通过 Java Native Interface(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应用程序最小化,您也可以检测到该事件。
希望这有帮助。
答案 1 :(得分:2)
不幸的是你不能这样做。 JavaFX需要一个专注的窗口。没有简单的方法可以实现Java所需的功能,因为出于安全考虑,它几乎无法控制操作系统。最好的办法是编写一个C应用程序来执行此操作,然后使用JNI从Java挂钩。
你会想要做两件事。
编写一个C程序,用于侦听操作系统上的全局事件。对于Windows,您可以在MSDN上找到有关此内容的更多信息,对于Mac和Linux,您需要使用X11库。
使用JNI在Java中链接您的C代码。这并不像听起来那么困难,这是一个非常好的教程:https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html
当然,你不必自己完成所有工作,有几乎所有东西的库。这个库为您完成了艰苦的工作,您可以使用它来实现您的目标:https://github.com/kwhat/jnativehook