【问题标题】:How do you get the current keyboard state globally? (i.e. what keys are currently depressed regardless of if the inquiring application has focus)如何全局获取当前键盘状态? (即,无论查询应用程序是否具有焦点,当前按下了哪些键)
【发布时间】:2012-04-08 10:10:44
【问题描述】:

我正在编写一个截屏实用程序,我希望能够在截屏时存储键盘和鼠标的当前状态。

对鼠标执行此操作很简单,因为以 related question 中描述的方式使用 PointerInfo 类会为您提供当前鼠标位置的屏幕坐标以及所需的单击信息。但是,我无法为键盘找到此类的模拟;所有与键盘相关的类似乎都是特定于焦点的。

那么,有没有办法在 Java 中获取当前键盘状态?

附:请记住,我正在寻找一个函数来调用以检索有关按下哪些键的信息,不是此类抑郁事件的侦听器。

【问题讨论】:

    标签: java keyboard keyboard-hook


    【解决方案1】:

    您可以做的是实现KeyListener 接口并为您感兴趣的所有键提供状态。

    如果您有兴趣检查屏幕截图上的箭头键是否被按下,例如,您可以实现此KeyListener 接口并覆盖keyPressed()keyReleased() 方法并设置您所在的那些键的状态对keyPressedkeyReleased 感兴趣。视事件而定。这样,当屏幕截图出现时,您就可以读取这些键的状态

    如果您需要这个解决方案是全球性的,无论应用程序的焦点是什么,您都可以用 C 编写一个小钩子,您可以将它与 Java 原生接口集成以侦听关键事件。 Java 不允许您在没有将侦听器附加到组件并且该组件具有焦点的情况下侦听关键事件。看看JNativeHook

    如果您只是在您的应用程序有焦点但在每个组件上需要它时,您可以不雅地将侦听器附加到您的所有组件,或者您可以编写自己的自定义 KeyEventDispatcher 并将其注册到 KeyBoardFocusManager。这样,只要您的应用程序具有焦点,无论组件具有特定焦点,您都可以捕获所有键盘事件。见:

    public class YourFrame extends JFrame {    
    
        public YourFrame() {
            // Finish all your layout and add your components
            //
    
            // Get the KeyboardFocusManager and register your custom dispatcher
            KeyboardFocusManager m = KeyboardFocusManager.getCurrentKeyboardFocusManager();
    
            m.addKeyEventDispatcher(new YourDispatcher());
        }
    
        private class YourDispatcher implements KeyEventDispatcher {
            @Override
            public boolean dispatchKeyEvent(KeyEvent e) {
                if (e.getID() == KeyEvent.KEY_TYPED) {
                    // Do something to change the state of the key
                } else if (e.getID() == KeyEvent.KEY_PRESSED) {
                    // Do something else
                }
                return false;
            }
        }
    
        public static void main(String[] args) {
            YourFrame yF = new YourFrame();
            yF.pack();
            yF.setVisible(true);
        }
    }
    

    【讨论】:

    • 感谢您的快速回复!我现在就试试——听起来应该可以。
    • 读取界面听起来好像这只是在某个 Jcomponent 具有焦点时拦截键,这不是我想要的。无论焦点如何,我都想听 globally 的按键。您提出的解决方案有没有办法做到这一点?
    • 我不认为 Java 会给你那种控制——即,不管应用程序焦点如何都实现一个 KeyListener。最好的方法是用更接近您正在使用的操作系统的语言(例如 C)编写全局侦听器。然后使用 Java Native Interface 与来自 C 的 Key 事件集成。
    • 但是如果你只需要在你的Java应用程序有焦点时才需要监听关键事件,你可以将KeyListener添加到所有组件中。非常不雅,我知道,但似乎是唯一的方法。
    猜你喜欢
    • 1970-01-01
    • 2016-03-28
    • 2012-09-04
    • 1970-01-01
    • 2021-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多