⚡ Ultra-fast global hotkey library for Java — system-wide hotkeys even when your app is not focused
// Quick Start — Global system-wide hotkeys
FastHotkey.loadLibrary();
// Register Ctrl+Shift+F1 as global hotkey
FastHotkey.register(1,
ModifierKeys.MOD_CONTROL | ModifierKeys.MOD_SHIFT,
KeyCodes.VK_F1,
id -> System.out.println("Hotkey pressed!")
);
// Start listening (works even when app is not focused)
FastHotkey.start();FastHotkey is a high-performance Java hotkey library that enables true global hotkeys — something standard Java cannot do. Unlike java.awt.Toolkit.getDefaultToolkit().addAWTEventListener(), which only captures keystrokes when your Java app is focused (same limitation as KeyListener), FastHotkey uses the native Windows RegisterHotKey API to capture hotkeys system-wide, even when your app is not focused. Built for global system-wide hotkeys, background key capture, automation shortcuts, and productivity tools.
Keywords: java hotkey alternative, global hotkeys, system-wide keyboard shortcuts, windows hotkey api, registerhotkey jni, java global hotkey listener, low-latency hotkeys, automation hotkeys, background hotkey capture, win32 hotkey
If you need system-wide hotkeys that work even when your app is not focused, low-latency key capture, or reliable global shortcuts, FastHotkey delivers native-level performance with Java simplicity.
- Why FastHotkey?
- Key Features
- Installation
- Quick Start
- API Reference
- Examples
- Project Structure
- Why Native Code?
- Requirements
- Build from Source
- How It Works
- Troubleshooting
- License
Standard Java (AWT, Swing, JavaFX) cannot register global hotkeys:
KeyListeneronly works when your app is focusedAWTEventListenerhas the same limitation- No system-wide keyboard shortcut support
- OS-level input throttling
FastHotkey solves this with native Windows API integration:
- System-wide hotkeys via
RegisterHotKey— works even when app is not focused - Low-latency input — Direct native callbacks, no polling
- Multiple hotkeys — Register unlimited shortcuts with unique IDs
- Auto-cleanup — Resources freed automatically on JVM shutdown
- Simple callback API — Clean lambda interface
- Global hotkeys: Capture hotkeys system-wide, not just when your app is focused
- High performance: Native JNI implementation - faster than JNA
- Simple API: Register hotkeys with just a few lines of code
- Callback-based: Clean lambda/callback interface for hotkey events
- Multiple hotkeys: Register unlimited hotkeys with unique IDs
- Auto-cleanup: Automatic resource cleanup on JVM shutdown
Add JitPack repository and dependency:
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependency>
<groupId>com.github.andrestubbe</groupId>
<artifactId>fasthotkey</artifactId>
<version>1.1.0</version>
</dependency>Add JitPack repository and dependency:
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
implementation 'com.github.andrestubbe:fasthotkey:1.1.0'
}Download the pre-built JAR with embedded native library:
📥 Download fasthotkey-1.1.0.jar
# Run the demo
java --enable-native-access=ALL-UNNAMED -cp fasthotkey-1.1.0.jar fasthotkey.Demo
# Use in your project
java --enable-native-access=ALL-UNNAMED -cp fasthotkey-1.1.0.jar;your-project.jar your.main.Classcompile.batThis compiles the C++ code to fasthotkey.dll and copies it to resources.
mvn clean packageimport fasthotkey.*;
// Load native library
FastHotkey.loadLibrary();
// Register Ctrl+Shift+F1
FastHotkey.register(1,
ModifierKeys.MOD_CONTROL | ModifierKeys.MOD_SHIFT,
KeyCodes.VK_F1,
id -> System.out.println("Hotkey pressed!")
);
// Start listening
FastHotkey.start();
// Your app runs here...
// Press Win+Q to quit in the demoRun the demo:
java -cp target/fasthotkey-1.0.0.jar fasthotkey.DemoFastHotkey.loadLibrary();Must be called before any other methods. Extracts and loads the native DLL from JAR resources.
boolean success = FastHotkey.register(
int id, // Unique hotkey ID (1-0xBFFF)
int modifiers, // Modifier keys (ALT, CTRL, SHIFT, WIN)
int vkCode, // Virtual key code (A-Z, F1-F12, etc.)
HotkeyCallback callback // Called when hotkey is pressed
);Modifiers: (combine with |)
ModifierKeys.MOD_ALTModifierKeys.MOD_CONTROLModifierKeys.MOD_SHIFTModifierKeys.MOD_WINModifierKeys.MOD_NOREPEAT- Don't trigger on key repeat
Key Codes:
- Letters:
KeyCodes.VK_AthroughKeyCodes.VK_Z - Numbers:
KeyCodes.VK_0throughKeyCodes.VK_9 - Function keys:
KeyCodes.VK_F1throughKeyCodes.VK_F12 - Special keys:
VK_ESCAPE,VK_SPACE,VK_RETURN,VK_TAB, etc.
FastHotkey supports two interception modes:
| Mode | Behavior | Use Case |
|---|---|---|
HotkeyMode.COOPERATIVE |
Uses RegisterHotKey. Fails if Windows or another app owns the hotkey. |
"Well-behaved" hotkeys that shouldn't override system shortcuts |
HotkeyMode.AGGRESSIVE (default) |
Uses low-level keyboard hook. Always works, overrides Windows hotkeys. | Ctrl+Space, Win+L, or any hotkey that must work regardless |
Default (AGGRESSIVE mode):
// Works even for Ctrl+Space (Windows IME), Win+L, etc.
FastHotkey.register(1,
ModifierKeys.MOD_CONTROL,
KeyCodes.VK_SPACE,
id -> System.out.println("Ctrl+Space works!")
);COOPERATIVE mode:
// Returns false if hotkey is already registered by Windows
boolean success = FastHotkey.register(1,
ModifierKeys.MOD_CONTROL,
KeyCodes.VK_C,
id -> System.out.println("Ctrl+C"),
HotkeyMode.COOPERATIVE // May fail if already taken
);
if (!success) {
System.out.println("Hotkey already in use by another app");
}FastHotkey.start(); // Start the message loop (background thread)
FastHotkey.stop(); // Stop and unregister all hotkeysFastHotkey.unregister(int id); // Unregister specific hotkey
FastHotkey.unregisterAll(); // Unregister all hotkeysFastHotkey.register(1,
ModifierKeys.MOD_CONTROL | ModifierKeys.MOD_SHIFT,
KeyCodes.VK_S,
id -> {
// Take screenshot
captureScreenshot();
}
);FastHotkey.register(2,
ModifierKeys.MOD_WIN | ModifierKeys.MOD_ALT,
KeyCodes.VK_T,
id -> {
// Launch terminal
Runtime.getRuntime().exec("cmd.exe /c start wt");
}
);// Hotkey 1: Ctrl+F1 - Action A
FastHotkey.register(1, ModifierKeys.MOD_CONTROL, KeyCodes.VK_F1,
id -> doActionA());
// Hotkey 2: Ctrl+F2 - Action B
FastHotkey.register(2, ModifierKeys.MOD_CONTROL, KeyCodes.VK_F2,
id -> doActionB());
// Hotkey 3: Win+Q - Quit
FastHotkey.register(3, ModifierKeys.MOD_WIN, KeyCodes.VK_Q,
id -> System.exit(0));
FastHotkey.start();fasthotkey/
├── native/ # C++ JNI implementation
│ ├── fasthotkey.h # Header file
│ └── fasthotkey.cpp # Implementation
├── src/main/java/fasthotkey/
│ ├── FastHotkey.java # Main API class
│ ├── HotkeyCallback.java # Callback interface
│ ├── KeyCodes.java # Virtual key code constants
│ ├── ModifierKeys.java # Modifier flag constants
│ └── Demo.java # Demo application
├── compile.bat # Build native DLL
├── pom.xml # Maven configuration
└── README.md
Java alone CANNOT handle global system-wide hotkeys. The standard Java KeyListener, KeyStroke, and AWTEventListener only capture keystrokes when your Java application window is focused. To capture hotkeys globally (while other apps are focused), you need native OS APIs like Win32 RegisterHotKey.
| Aspect | JNI (FastHotkey) | JNA | Java Alone |
|---|---|---|---|
| Global Hotkeys | ✅ Full support | ✅ Full support | ❌ Cannot - only in-app |
| Background Capture | ✅ Works always | ✅ Works always | ❌ Cannot - app must be focused |
| Performance | Fastest - direct native calls | 10-50x slower (libffi overhead) | N/A |
| Development | Write C++, compile per-platform | Pure Java, define interfaces | N/A |
| Deployment | Bundle platform-specific DLLs | Single JAR (libffi handles it) | N/A |
| Maintenance | Harder (C++ code + build scripts) | Easier (just Java interfaces) | N/A |
FastHotkey uses JNI for maximum performance and to maintain consistency with the FastJava ecosystem (FastClipboard, FastRobot). While JNA would work for simple hotkey registration, JNI delivers the lowest possible latency for hotkey event handling.
- Windows 10/11 (Win32 API)
- Java 17+
- Visual Studio 2019+ (for building native code)
- JDK 17 or later
- Visual Studio with C++ workload
- Maven 3.8+
-
Compile native DLL:
compile.bat
-
Build Java library:
mvn clean package
-
Run demo:
java -cp target/fasthotkey-1.0.0.jar fasthotkey.Demo
FastHotkey uses the Windows API:
- RegisterHotKey - Registers global hotkeys with the system
- Message-only window - Creates an invisible window to receive WM_HOTKEY messages
- Message loop - Runs a Windows message loop in a background thread
- JNI callbacks - Calls Java callbacks when hotkeys are pressed
The DLL requires the Visual C++ Redistributable. Install it from Microsoft.
Set JAVA_HOME environment variable to your JDK installation.
Some hotkeys may be reserved by Windows or other apps. Try different combinations.
MIT License - See LICENSE file.
- FastClipboard - Ultra-fast clipboard access
- FastRobot - High-performance screen capture
- FastGraphics - GPU-accelerated graphics
- FastTheme - OS-aware Display/Theme monitor
