Toolkit.getDefaultToolkit()。getLockingKeyState(...)在程序执行期间永远不会更新

时间:2014-04-01 12:44:19

标签: java swing keyboard awt

我遇到Toolkit.getDefaultToolkit().getLockingKeyState(...)永远不会更新的问题。它在第一次查询时正确报告,然后当我使用键盘更改状态时,更改永远不会反映出来。

这是设计的(在API文档中似乎不是这样),一个错误,还是我的代码中有什么东西?

这是一个简短的,自包含的示例,用于演示此问题:

public class LockingStateIssue {
    public static void main(String[] args) {
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override public void run() {
                if (Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_NUM_LOCK)) {
                    System.out.print("*");
                } else {
                    System.out.print(".");
                }
            }
        }, 0, 200);
    }
}

运行时,在我的Windows机器上,使用Java 1.7.0_45,它会打印.......*********,具体取决于num lock键的初始状态,但绝不会像{{1像切换按钮一样,我期待它。

1 个答案:

答案 0 :(得分:3)

  1. 在没有visible Java container的普通Java中没有正确的方法,并且在Windows中也有焦点,KeyLoggers在Java中被阻止,

  2. (可能不是主要问题,但也没有任何内容可以打印)来自util.Timer的循环不在EDT中,更多在Concurency in Swing,Toolkit来自AWT包,ED​​T问题对大多数人都有效也是AWT包

  3. 为我工作(前两点,满足要求的情况......),用于测试目的,尝试在此程序执行期间将焦点移动到Windows操作系统中的另一个活动窗口

  4. import java.awt.AWTEvent;
    import java.awt.EventQueue;
    import java.awt.Toolkit;
    import java.awt.event.AWTEventListener;
    import java.awt.event.ActionEvent;
    import java.awt.event.KeyEvent;
    import javax.swing.AbstractAction;
    import javax.swing.Action;
    import javax.swing.JFrame;
    
    public class ToolkitAndNumLock {
    
        private javax.swing.Timer timer = null;
        private JFrame frame = new JFrame();
    
        public ToolkitAndNumLock() {
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(400, 300);
            frame.setVisible(true);
            start();
            //uncomment Toolkit.getXxx listening a KeyEvents, you can (start();) block SwingTimer 
            //Toolkit.getDefaultToolkit().addAWTEventListener(listener, AWTEvent.KEY_EVENT_MASK);
        }
        AWTEventListener listener = new AWTEventListener() {
            @Override
            public void eventDispatched(AWTEvent event) {
                if (event instanceof KeyEvent) {
                    KeyEvent ke = (KeyEvent) event;
                    if (ke.getID() == KeyEvent.KEY_PRESSED) {
                        if (ke.getKeyCode() == KeyEvent.VK_CAPS_LOCK) {
                            System.out.println("CapsLock Pressed");
                        }
                        if (ke.getKeyCode() == KeyEvent.VK_SCROLL_LOCK) {
                            System.out.println("ScrollLock Pressed");
                        }
                        if (ke.getKeyCode() == KeyEvent.VK_NUM_LOCK) {
                            System.out.println("NumLock Pressed");
                        }
                    }
                }
            }
        };
    
        private void start() {
            timer = new javax.swing.Timer(2500, updateCol());
            timer.setRepeats(true);
            timer.start();
        }
    
        public Action updateCol() {
            return new AbstractAction("text load action") {
                private static final long serialVersionUID = 1L;
                private Boolean bol = true;
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_NUM_LOCK)) {
                        System.out.println("true");
                    } else {
                        System.out.println("false");
                    }
                    if (bol) {
                        Toolkit.getDefaultToolkit().setLockingKeyState(KeyEvent.VK_NUM_LOCK, true);
                    } else {
                        Toolkit.getDefaultToolkit().setLockingKeyState(KeyEvent.VK_NUM_LOCK, false);
                    }
                    bol = !bol;
                }
            };
        }
    
        public static void main(String args[]) {
            Runnable runner = new Runnable() {
                @Override
                public void run() {
                    new ToolkitAndNumLock();
                }
            };
            EventQueue.invokeLater(runner);
        }
    }