【问题标题】:Java System-Wide Keyboard ShortcutJava 系统范围的键盘快捷键
【发布时间】:2010-10-02 07:21:03
【问题描述】:

是否有任何方法或库来获得系统范围(全局)的键盘快捷键 在 Java 应用程序中执行操作?

【问题讨论】:

    标签: java keyboard system shortcut


    【解决方案1】:

    更新:我不知道您是否可以从 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
        }
    }
    

    我认为可能还有其他方法可以使用动作映射来完成全局按键操作。我其实用过上面的方法

    【讨论】:

    • @basszero:关于你的更新,是的,java 应用程序必须有焦点才能工作。
    【解决方案2】:

    没有,但是在windows中你可以使用这个:

    jintellitype

    不幸的是,对于 Linux 和 OSX,我一无所知,这可能就是为什么它没有随 java 开箱即用的原因。

    如果您发现其他平台请在此处发布:)

    只是出于好奇,你用它做什么?

    【讨论】:

    • 感谢您的回复。我想要这个功能,所以我的用户可以从系统的任何地方弹出一个窗口。它在 Windows 应用程序中很常见,但我想要跨平台支持。
    • 是的,好吧,我想我们将不得不等待。我听说这在 Linux 和 OSX 中很容易做到,我不知道为什么已经编写了中途平台 3rd 方。 Sun 肯定不支持它。
    • Jintellitype 提到了为 Linux 提供相同功能的 JxGrabKey (sourceforge.net/projects/jxgrabkey) 项目。
    【解决方案3】:

    对于 Windows,您需要一个键盘挂钩 dll。 您可以从 java 初始化您的 dll,这将导致它注册侦听器。 你会得到你需要的。检查 msdn 是否有 dll 挂钩或键盘挂钩。其中之一应该设置你。

    对于 linux 我认为这应该更容易,但我自己从未做过。

    http://ubuntuforums.org/showthread.php?t=864566

    Google 的“linux 监听全局按键”(无引号)的第一个结果出现了一些我认为可以帮助您适应 X11 环境的东西

    OSX 可能只能使用接近此的解决方案。 但最后,您可能需要一个适用于每个平台的 dll,除非 JNA 可以毫无问题地做到这一点,否则最坏的情况已经过去了。

    【讨论】:

      【解决方案4】:

      JDIC(Java 桌面集成)可以提供帮助
      https://jdic.dev.java.net/

      对我来说似乎有点无人维护。我不确定。
      如果有人知道更多,请报告!
      我对这个功能也很感兴趣。

      【讨论】:

        【解决方案5】:

        我是 JIntellitype 的作者,我可以告诉你一个事实,这必须在 DLL 中本地完成并从 Java JNI 调用,就像 JIntellitype 所做的那样。这是一个在 JDK 中未实现的 OS 级别挂钩,因此必须使用 JIntellitype 和 jxGrabKey 等库。据我所知,还没有人为 OSX 写过。

        JIntellitype 在 Github 上是开源的,所以如果您想了解它的工作原理,请查看 source 代码

        【讨论】:

        • 是否有使用 JNA 的内置功能?
        【解决方案6】:

        我刚刚找到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());
            }
        }
        

        检查修饰符是基于位掩码(我们都应该知道但总是忘记的东西:-P):

            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){...}
        

        这是来自here的修改示例

        您还应该修改默认的日志记录行为,否则它将向控制台发送垃圾邮件:

        // 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);
        

        代码示例来自here

        【讨论】:

          【解决方案7】:

          您现在可以使用 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);
                      }
                  });
          

          我希望这对某人有所帮助

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-12-07
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多