JavaFX:如何在屏幕上的任何位置检测鼠标/键事件?

时间:2017-08-31 16:43:03

标签: java events javafx system listeners

我试图抓住Java(fx)中的鼠标/键事件,即使应用程序窗口未集中 ... 我正在创建类似于screenrecorder的东西,我想通过按“F9”之类的键来停止录制,所以我需要检测事件。这可能吗? 是否可以使用系统监听器

〜亨利

2 个答案:

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

关键输出: Global key listener output

鼠标输出

Global mouse listener output

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

希望这有帮助。

答案 1 :(得分:2)

不幸的是你不能这样做。 JavaFX需要一个专注的窗口。没有简单的方法可以实现Java所需的功能,因为出于安全考虑,它几乎无法控制操作系统。最好的办法是编写一个C应用程序来执行此操作,然后使用JNI从Java挂钩。

你会想要做两件事。

  1. 编写一个C程序,用于侦听操作系统上的全局事件。对于Windows,您可以在MSDN上找到有关此内容的更多信息,对于Mac和Linux,您需要使用X11库。

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

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