[Tutorial] jnativehook : Control native mouse and keyboard calls outside Java

In programming a “hook” is a way for a programmer to access already existing code and modify it to his specification. A mouse hook in java is quite similar to a MouseListener, except while a MouseListener functions only within the swing or awt component it is bound to, a native mouse hook can intercept mouse calls from all over the system. This makes it immensely useful for various kinds of programs. Here, I’ll try to explain how the jnativehook library can be used to detect mouse and keyboard calls.

jnativehook is an opensource native hook library for Java. It functions as a Global Mouse and Keyboard Listener.

jnativehook can be downloaded from its official GitHub page here :
https://github.com/kwhat/jnativehook/releases
Extract and add jnativehook to your build path.

Mouse Hook :
To use a Mouse Hook in your program, have your class implement NativeMouseInputListener.
Methods to override :
public void nativeMouseClicked(NativeKeyEvent e);
public void nativeMousePressed(NativeKeyEvent e);
public void nativeMouseReleased(NativeKeyEvent e);
public void nativeMouseMoved(NativeKeyEvent e);
public void nativeMouseDragged(NativeKeyEvent e);

These methods are self explanatory. Put the code you want to run when your mouse is clicked, pressed, released, moved or dragged in these methods.

To register jnativehook and cause it to start listening to mouse events globally, enclose this line in a try catch block :
GlobalScreen.registerNativeHook();

To unregister it :
GlobalScreen.unregisterNativeHook();

For a program which detects and outputs which mouse actions have been performed :

import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.mouse.NativeMouseEvent;
import org.jnativehook.mouse.NativeMouseInputListener;

public class GlobalMouseListenerExample implements NativeMouseInputListener {
public void nativeMouseClicked(NativeMouseEvent e) {
System.out.println("Mouse Clicked: " + e.getClickCount());
}

public void nativeMousePressed(NativeMouseEvent e) {
System.out.println("Mouse Pressed: " + e.getButton());
}

public void nativeMouseReleased(NativeMouseEvent e) {
System.out.println("Mouse Released: " + e.getButton());
}

public void nativeMouseMoved(NativeMouseEvent e) {
System.out.println("Mouse Moved: " + e.getX() + ", " + e.getY());
}

public void nativeMouseDragged(NativeMouseEvent e) {
System.out.println("Mouse Dragged: " + e.getX() + ", " + e.getY());
}

public static void main(String[] args) {
try {
GlobalScreen.registerNativeHook();
}
catch (NativeHookException ex) {
System.err.println("There was a problem registering the native hook.");
System.err.println(ex.getMessage());

System.exit(1);
}

// Construct the example object.
GlobalMouseListenerExample example = new GlobalMouseListenerExample();

// Add the appropriate listeners.
GlobalScreen.addNativeMouseListener(example);
GlobalScreen.addNativeMouseMotionListener(example);
}
}

Similarly for a Keyboard Hook have your class implement NativeKeyListener.
Methods to override :

public void nativeKeyPressed(NativeKeyEvent e)
public void nativeKeyReleased(NativeKeyEvent e)
public void nativeKeyTyped(NativeKeyEvent e)

The method NativeKeyEvent.getKeyText(e.getKeyCode()) will return the key that was pressed. Where e is the NativeKeyEvent accepted by each of the overriden methods.


import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.keyboard.NativeKeyEvent;
import org.jnativehook.keyboard.NativeKeyListener;

public class GlobalKeyListenerExample implements NativeKeyListener {
public void nativeKeyPressed(NativeKeyEvent e) {
System.out.println("Key Pressed: " + NativeKeyEvent.getKeyText(e.getKeyCode()));

if (e.getKeyCode() == NativeKeyEvent.VC_ESCAPE) {
GlobalScreen.unregisterNativeHook();
}
}

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

public static void main(String[] args) {
try {
GlobalScreen.registerNativeHook();
}
catch (NativeHookException ex) {
System.err.println("There was a problem registering the native hook.");
System.err.println(ex.getMessage());

System.exit(1);
}

GlobalScreen.addNativeKeyListener(new GlobalKeyListenerExample());
}
}

Overriding the nativeKeyPressed() method like above will output the KeyText of every button pressed. It will also unregister the nativehook if the “ESC” key is pressed.

Karthi

Karthikeyan M : Geek, Gamer, Coder, Blogger - he shares his love of Technology in the form of tutorials, reviews, and how-to’s. An avid reader, he is a student at SRM university pursuing his B.Tech. in Information Technology.

Leave a Reply