我有JFrame必须检测大写锁定是打开还是关闭。如果我将Window聚焦,则一切正常,程序将通过KeyListener检测到大写锁定状态的更改。当窗口最小化时,我无法检查大写锁定状态,因此我在用户重新调整窗口聚焦后检查状态。但是随后,检查返回了我获得的最后一个Caps Lock状态,而不是当前的状态。
JFrame frame;
public example() {
frame = new JFrame();
frame.setSize(400, 400);
frame.setVisible(true);
frame.addWindowFocusListener(new WindowFocusListener() {
@Override
public void windowGainedFocus(WindowEvent e) {
System.out.println("Caps Lock Status: " + Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_CAPS_LOCK));
}
@Override
public void windowLostFocus(WindowEvent e) {
// nothing to do
}
});
}
如果在窗口打开时我的大写锁定处于关闭状态,而窗口未聚焦时我正在打开大写锁定。然后,我希望窗口重新聚焦后,程序中的结果为true。
我感谢各种建议,谢谢!
最佳答案
正如@camickr在注释部分正确指出的,它与错误有关。可能是Windows工具包。为了使这项工作有效,我尝试了一些尝试,唯一稳定的方法(测试了约100次)是在两次按下/取消按下CAPS LOCK两次(一次更改其状态,另一次将其恢复),并且在然后从工具箱中询问值。为了实现这一点(休眠线程),我们将需要使用sleep
。我创建了一个SwingWorker
类,该类接受一个SwingWorker
参数,并在完成后接受它。使用者中的Consumer<Boolean>
值表示大写锁定是打开还是关闭。
看一看:
public class CapsLockDetectWorker extends SwingWorker<Boolean, Void> {
private Consumer<Boolean> consumer;
private static final int CAPS_LOCK = KeyEvent.VK_CAPS_LOCK;
public CapsLockDetectWorker(Consumer<Boolean> consumer) {
this.consumer = consumer;
}
@Override
protected Boolean doInBackground() throws Exception {
Robot robot = new Robot();
robot.keyPress(CAPS_LOCK);
robot.keyRelease(CAPS_LOCK);
Thread.sleep(3);
robot.keyPress(CAPS_LOCK);
robot.keyRelease(CAPS_LOCK);
Thread.sleep(3);
return Toolkit.getDefaultToolkit().getLockingKeyState(CAPS_LOCK);
}
@Override
protected void done() {
try {
Boolean isCapsOn = get();
consumer.accept(isCapsOn);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
以及如何使用它的示例:
public class CapsLockDetection {
private JFrame frame;
public CapsLockDetection() {
frame = new JFrame();
frame.setSize(400, 400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.addWindowFocusListener(new WindowFocusListener() {
@Override
public void windowGainedFocus(WindowEvent e) {
new CapsLockDetectWorker(b -> {
System.out.println("ENABLED CAPS LOCK:" + b);
}).execute();
}
@Override
public void windowLostFocus(WindowEvent e) {
// nothing to do
}
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new CapsLockDetection();
});
}
}
当然,如果您的计算机上有一个
Boolean
按钮带有指示灯(或者您的键盘上某个地方有一个按钮),您将看到它闪烁(关闭/打开)...我知道它看起来很傻,但是我认为您不会发现更好的东西。