如何将 KeyEvent 发送到 JFrame 组件?

How to send an KeyEvent to JFrame Component?

所以我正在尝试将 KeyEvent 发送到 JFrame 组件。就像当你在 window 正常聚焦时按下一个键时,它会向 JFrame 发送一个 KeyEvent 并触发一些东西。但是我该如何模拟呢?没有Robotclass,像直接在JFrame组件中输入KeyEvent?

我发现了如何向它发送 MouseEvents,您可以通过创建 MouseEvent 对象并调用 component.dispatchEvent(MouseEvent) 来实现。然后将鼠标事件发送到 JFrame,它完美地工作。但是用 KeyEvents 做同样的事情似乎并不奏效。我已经尝试了几乎所有的方法,比如在 KeyEvent 等之前发送 FocusEvent。似乎什么都行不通。

这是我试图发送给它的 KeyEvent 对象。它使用与有效的 MouseEvent 相同的目标和内容。所以这应该不是问题,问题是发送到组件不起作用。 “键”参数是键 ID,如 KeyEvent。VK_2

KeyEvent ke = new KeyEvent(target, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, key, (char)key);
KeyEvent ke = new KeyEvent(target, KeyEvent.KEY_RELEASED, System.currentTimeMillis(), 0, key, (char)key);

您可以添加一个 KeyListener,假设这是您想要的。每个字符都有一个字符代码,这意味着 KeyEvent.VK_2 可以简化为与之等效的代码。只是为了更简单。

public class Foo {
    public static void main(String[] args) {
       JFrame frame = new JFrame();
       frame.setSize(300,300);
       frame.setVisible(true);
       frame.addKeyListener(new KeyListener() {

           @Override
           public void keyPressed(KeyEvent e) {
                if(e.getKeyChar() == 'a'){
                    doSomething();
                }
           }
           @Override
           public void keyTyped(KeyEvent e) {
           }

           @Override
           public void keyReleased(KeyEvent e) {

           }
       });
    }
}

我用控制台输出替换了 doSomething();,所以只要我在框架上,它就会监听我的按键事件,当我按下 a 时,它会为我执行一些代码。

KeyEvents 实际上被正确发送了。但是什么也没有发生,因为我只发送新闻和发布事件,我发现在发送新闻事件之后你需要发送一个类型化的事件,然后是发布事件。在那之后,KeyEvents 真正起作用了。

举个例子:

    int key = KeyEvent.VK_2;
    Component target = null;
    
    KeyEvent pressed = new KeyEvent(target, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, key, (char)key, 1);
    KeyEvent typed = new KeyEvent(target, KeyEvent.KEY_TYPED, System.currentTimeMillis(), 0, 0, (char)key);
    KeyEvent released = new KeyEvent(target, KeyEvent.KEY_RELEASED, System.currentTimeMillis(), 0, key, (char)key, 1);
    
    EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue();
    queue.postEvent(pressed);
    queue.postEvent(typed);
    queue.postEvent(released);

您是否尝试过根据文档使用 Robot class:

This class is used to generate native system input events for the purposes of test automation, self-running demos, and other applications where control of the mouse and keyboard is needed

一个例子是:

someComponent.requestFocusInWindow(); // need to focus the component we want the key events to be sent too

try { 
    Robot robot = new Robot(); 
    robot.keyPress(KeyEvent.VK_ENTER); 
} catch (AWTException e) { 
    e.printStackTrace(); 
}