在普通Java中,没有可见的Java容器也没有正确的方法,而在Windows中也有焦点,KeyLoggers在Java中被阻止,
(不是主要问题,但也不会打印任何内容)来自util.Timer的循环不在EDT中,更多在Swing的Concurency中,工具包来自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() {@Overridepublic 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); }}解决方法
我有一个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('.');} }},200); }}
在运行Windows的Java机器上,使用Java 1.7.0_45时,它会打印.......或*********根据numlock键的初始状态进行打印,但是..**.**在切换按钮时,不会像我期望的那样混合打印。