是否有任何方法或库可以在Java应用程序中获取系统范围(全局)的键盘快捷方式来执行操作?
我是JIntellitype的作者,我可以告诉你,这必须在DLL中本地完成并从Java JNI调用,就像JIntellitype一样。这是一个未在JDK中实现的操作系统级钩子,因此必须使用类似于JIntellitype和jxGrabKey的库。据我所知,目前还没有人为OSX编写过一个。
JIntellitype在Github上是开放源代码的,如果想了解它的工作原理,请查看源代码。
我刚刚发现了https://github.com/kwhat/jnativehook
它似乎是跨平台的。
这里是他们用于监听按键的示例代码:
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());
}
}
boolean isAltPressed = (e.getModifiers() & NativeKeyEvent.ALT_MASK) != 0;
boolean isShiftPressed = (e.getModifiers() & NativeKeyEvent.SHIFT_MASK) != 0;
你可以将这个与 KeyCode 结合起来:
if (e.getKeyCode() == NativeKeyEvent.VK_2 && isShiftPressed && isAltPressed){...}
这是从这里修改的示例。
您还应该修改默认的日志记录行为,否则它会在控制台上生成垃圾信息:
// Get the logger for "org.jnativehook" and set the level to warning.
Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
logger.setLevel(Level.WARNING);
// Don't forget to disable the parent handlers.
logger.setUseParentHandlers(false);
代码示例来自这里
目前来看,没有适用于Linux和OSX的解决方案,但在Windows中可以使用此方法:
不幸的是,我并不知道其他平台是否有类似的解决方案,这也许是为什么java不会自带该功能的原因。
如果你发现了其他平台的解决方法,请在这里分享一下 :)
只是出于好奇,您是想要做些什么呢?
http://ubuntuforums.org/showthread.php?t=864566
Google的第一个搜索结果为“linux listen for global key presses”(不加引号),返回了我认为对于X11环境将会对您有所帮助的内容。更新:我不知道是否可以从JVM外部钩取事件。我认为Swing/AWT组件必须具有焦点才能正常工作。
您需要钩取Java AWT事件队列,以确保您可以获得全局(jvm范围内)按键。
使用
EventQueue ev = Toolkit.getSystemEventQueue();
// MyCustomEventQueue extends EventQueue and processes keyboard events in the dispatch
ev.push(new MyCustomEventQueue());
class MyEventQueue extends EventQueue
{
protected void dispatchEvent(AWTEvent event)
{
// all AWTEvents can be indentified by type, KeyEvent, MouseEvent, etc
// look for KeyEvents and match against you hotkeys / callbacks
}
}
我认为有其他方法可以使用动作映射来完成全局按键。实际上,我已经使用了上述方法。
JDIC(Java桌面集成)可以帮助
https://jdic.dev.java.net/
对我来说似乎有点不维护。 我不确定。
如果有人知道更多,请报告!
我也非常感兴趣这个功能。
现在您可以使用JNA - 请参见https://github.com/tulskiy/jkeymaster
我已经在Windows 10笔记本电脑上轻松测试过,但我个人没有在其他平台上进行过测试 - 显然它也适用于MacOS和“基于X11的系统(理论上仅在某些Linux发行版和PCBSD上进行了测试)”。
设置不应该很困难 - 您需要slf4j才能使其运行。
您不需要构建jar文件。
例如,此代码有效地禁用了“f”键并记录了您按下它的事实。
import com.tulskiy.keymaster.common.Provider;
import com.tulskiy.keymaster.common.HotKeyListener;
import com.tulskiy.keymaster.common.HotKey;
import javax.swing.*;
// ...
Provider provider = Provider.getCurrentProvider(false);
provider.register(KeyStroke.getKeyStroke("F"), new HotKeyListener() {
public void onHotKey(HotKey hotKey) {
System.out.println(hotKey);
}
});