我有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按钮带有指示灯(或者您的键盘上某个地方有一个按钮),您将看到它闪烁(关闭/打开)...

我知道它看起来很傻,但是我认为您不会发现更好的东西。

10-07 22:39