Search code examples
javaeventsjavafxsystemlisteners

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


Solution

  • 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: Global key listener output

    Mouse Output

    Global mouse listener output

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

    Hope this helps.