简体   繁体   中英

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

I´m trying to catch mouse/key events in Java(fx), even if the application window isn´t focused ... I´m creating something like a screenrecorder and I want to stop the recording by pressing a key like "F9" , so I need to detect the event. Is this possible? Is there something like a system listener I can use?

~Henri

It is possible but standard Java does not have access to key-strokes or mouse events if the registered component is not in focus.

In order to achieve this you need to use native code via the Java Native Interface (JNI) . This enables Java code to call native applications (programs specific to a hardware and operating system platform) and libraries written in other languages such as C and C++.

Luckily, there is a third party library JNativeHook that was designed exactly for what you need. You can find it here: https://github.com/kwhat/jnativehook

If you are using Maven for dependency management you can install it easily. Here is a working example:

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

Key Output: 全局键监听器输出

Mouse Output

全局鼠标监听器输出

This way you can detect the event even if your Java application is minimised.

Hope this helps.

Unfortunately you cannot do this. JavaFX requires a focused window. There is no easy way to achieve what you want with Java, as it gives you very little control over the OS for security purposes. The best thing to do would be to write a C application to do this, then hook into it from Java using JNI.

You would want to do two things.

  1. Write a C program that listens for global events on your OS. For Windows you can find more info about this on MSDN, and for mac and linux you will need to use the X11 libraries.

  2. Use JNI to link your C code in Java. This isn't as difficult as it may sound, here is a pretty good tutorial on it: https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html

Of course you don't have to do all that work yourself, there are libraries for just about everything out there. This library does the hard work for you and you can use it to achieve your goal: https://github.com/kwhat/jnativehook

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM