java - 机器人方法是否需要在事件队列上运行?

标签 java swing thread-safety awtrobot

Robot 是 AWT 库的一部分,但它似乎与库中的大多数其他部分大不相同。我正在创建一个 Swing GUI,它将 Swing 与 Java Native Access (JNA) 和 Robot 混合在一起,以允许 Java 驱动某些 MS Windows/Citrix 工作程序。我的直觉是,由于 Robot 将在“平台的 native 输入队列”上对事件进行排队,所以我最不想做的就是在 EDT 上运行它,但另一方面,AWT 和 Swing 库中的大多数类应该在 Swing 事件线程上 运行。因此,为了在我的脑海中澄清这一点,让我问一个尽可能具体的问题:

机器人方法(尤其是按键按下和释放、鼠标移动、鼠标按下和释放)应该在 Swing 事件调度线程 (EDT) 上运行还是在其外运行?

最佳答案

您提到的 Robot 方法应该在 EDT 上运行。查看源代码后发现,这些“事件”方法中的每一个都有一个共同点(afterEvent 调用):

public synchronized void keyPress(int keycode) {
    checkKeycodeArgument(keycode);
    peer.keyPress(keycode);
    afterEvent();
}

public synchronized void mousePress(int buttons) {
    checkButtonsArgument(buttons);
    peer.mousePress(buttons);
    afterEvent();
}

// etc

private void afterEvent() {
    autoWaitForIdle();
    autoDelay();
}

private void autoWaitForIdle() {
    if (isAutoWaitForIdle) {
        waitForIdle();
    }
}

public synchronized void waitForIdle() {
    checkNotDispatchThread();
    /* snip */
}

private void checkNotDispatchThread() {
    if (EventQueue.isDispatchThread()) {
        throw new IllegalThreadStateException("Cannot call method from the event dispatcher thread");
    }
}

如果您在 Robot.isAutoWaitForIdle 时在 EDT 上调用这些方法中的任何一个为 true,将抛出异常。按理说,即使 isAutoWaitForIdlefalse,也不应从 EDT 调用这些方法。

关于java - 机器人方法是否需要在事件队列上运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10468432/

相关文章:

java - 清除数独表

java - 使用构建器/工厂模式确保内存可见性

java - PDFBox用java并排合并2个pdf文件

java - 从 tomcat7 连接到 Tuxedo

java - Swing : change the icon of jframe

java - 如何在显示面板之前获取 Miglayout 管理器设置的面板边界?

java - 线程安全地从一个列表中删除/添加元素到另一个列表

Objective-C 线程安全代码以防止崩溃

Java 序列化异常消息

java - 为什么 Visual VM 将这个 String 类的实例显示为零?