如何将 KeyEvent 发送到 JFrame 组件?

Posted

技术标签:

【中文标题】如何将 KeyEvent 发送到 JFrame 组件?【英文标题】:How to send an KeyEvent to JFrame Component? 【发布时间】:2021-04-18 14:43:11 【问题描述】:

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

我发现了如何将 MouseEvents 发送给它,您可以通过创建一个 MouseEvent 对象并调用 component.dispatchEvent(MouseEvent) 来做到这一点。然后将鼠标事件发送到 JFrame 并且它工作得很好。但是用 KeyEvents 做同样的事情似乎不起作用。我已经尝试了几乎所有的事情,比如在 KeyEvent 等之前发送 FocusEvent。似乎没有任何效果。

这是我试图发送给它的 KeyEvent 对象。它使用与有效的 MouseEvent 相同的目标和东西。所以这应该不是问题,问题是发送到组件不起作用。 “key”参数是 KeyEvent.VK_2 之类的密钥 id

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);

【问题讨论】:

你为什么要向框架发送“2”。 KeyEvent 通常被分派给具有焦点的组件。框架不会有焦点,框架上的组件将有焦点。因此,我认为您尝试的解决方案不会解决问题。你想解决什么问题。发布您的minimal reproducible example 来证明问题。 是的,我的意思是 JFrame 中的一个组件,抱歉。所以我的问题是你如何将 KeyEvent 发送到组件? component.dispatchEvent() 不适用于 KeyEvents,但至少对我适用于 MouseEvents。 【参考方案1】:

您是否尝试过按照文档使用 Robot 类:

此类用于生成本地系统输入事件,用于测试自动化、自运行演示和其他需要控制鼠标和键盘的应用程序

一个例子是:

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(); 
 

【讨论】:

是的,我尝试使用机器人。但是机器人接管了你真正的键盘和鼠标,这不是我想要的。但我现在想出了如何发送 KeyEvents。【参考方案2】:

假设这是您想要的,您可以添加一个 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时,它会为我执行一些代码。

【讨论】:

谢谢,但我正在寻找一种方法来发送关键事件而不是听它们。 哦,就像在按下按钮的组件中做某事一样?还是机器人之类的东西?【参考方案3】:

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);

【讨论】:

以上是关于如何将 KeyEvent 发送到 JFrame 组件?的主要内容,如果未能解决你的问题,请参考以下文章

如何将关键事件发送到 QWebElement?

如何将 jscrollpane 添加到 jframe?

如何将值从一个JFrame传递到另一个JFrame?

如何将两个 JPanel 添加到中心的 JFrame?

如何将多个 MouseListeners 添加到单个 JFrame?

我如何将jframe对齐到netbeans中的窗口中心[关闭]