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

Posted

技术标签:

【中文标题】JavaFX:如何在屏幕上的任何位置检测鼠标/键事件?【英文标题】:JavaFX: How to detect mouse/key events anywhere on screen? 【发布时间】:2018-02-09 16:55:03 【问题描述】:

我正在尝试在 Java(fx) 中捕捉 鼠标/按键事件,即使 应用程序窗口没有聚焦... 我正在创建类似屏幕录像机的东西,我想通过按 “F9” 之类的键来停止录制,所以我需要检测事件。这可能吗? 有没有可以使用的系统监听器

~亨利

【问题讨论】:

不,我不想存档。 @JavaProgrammer.002 刚刚发布了一个答案,这是一种快速简便的方法来满足您的需求。只需将库添加为依赖项即可。 【参考方案1】:

这是可能的,但如果注册的组件不在焦点上,标准 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 应用程序被最小化,您也可以检测到事件。

希望这会有所帮助。

【讨论】:

您可能还需要这个答案来包装 JavaFX 事件:***.com/questions/45403575/…【参考方案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

【讨论】:

以上是关于JavaFX:如何在屏幕上的任何位置检测鼠标/键事件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JavaFX 中的 SplitPane Divider 上检测鼠标拖动事件

如何 GetMousePosition 在屏幕上的任何位置,在窗口(或任何视觉)边界之外

如何在2个部分重叠的位置独立检测悬停s?

在 JPanel 上的任何位置检测鼠标进入/退出事件

检测触摸何时开始在屏幕上的任何位置,即使是在 UIButton 上

如何在 Qt 中获取鼠标在屏幕上的位置?