java-Toolkit.getDefaultToolkit().getLockingKeyState(…)在程序执行期间从不更新

我有一个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机器上,使用Java 1.7.0_45时,它会根据num lock键的初始状态打印…….或*********,但绝不会像.. **.**就像我期望的那样,在切换按钮时.

解决方法:

>在没有visible Java container的纯Java中没有正确的方法,并且也将焦点放在Windows中,KeyLoggers在Java中被阻止,
>(不可能是主要问题,但是也不会打印任何内容)来自util.Timer的循环不在EDT中,更多内容在Concurency in Swing中,Toolkit来自AWT软件包,EDT问题也适用于大多数AWT软件包
>为我工作(在满足前两点的情况下..),出于测试目的,请在此程序执行期间尝试将焦点移至Windows OS中的另一个活动窗口

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);
    }
}
上一篇:【BZOJ-1218】激光炸弹 前缀和 + 枚举


下一篇:理解position定位