【问题标题】:Should we use EventQueue.invokeLater for any GUI update in a Java desktop application?我们应该使用 EventQueue.invokeLater 来更新 Java 桌面应用程序中的任何 GUI 吗?
【发布时间】:2010-08-22 11:53:40
【问题描述】:

我知道通过这个方法,runnable参数是提交给系统EventQueue的。 但是是否应该使用这种方法完成所有 GUI 更新?我的意思是,如果我想说,更改 JButton 的文本,我应该使用这样的东西:

java.awt.EventQueue.invokeLater(new Runnable() {
      public void run() {
         jButton1.setText("changed text");
      }
});

如果我应该使用这种方法,我们可以使用什么模式来避免这种重复的代码?

【问题讨论】:

  • 注意:慢代码也需要去那里以保持摆动响应
  • @nash 如果以下任何答案回答了您的问题,您能否将其标记为已回答?

标签: java swing thread-safety


【解决方案1】:

当您想从另一个不是 UI 线程(事件调度线程)的线程更新您的 UI 时,您只需要使用 invokeLater

假设您有一个按钮单击处理程序,并且您想在有人单击按钮时更改标签的文本。那么直接设置标签文字就完美保存了。这是可能的,因为按钮单击事件的处理程序在 UI 线程中运行。

然而,假设在另一个按钮单击时,您启动了另一个线程,该线程完成了一些工作,并且在该工作完成后,您想要更新 UI。然后你使用invokeLater。此方法可确保您的 UI 更新在 UI 线程上执行。

所以在很多情况下,你不需要invokeLater,你可以直接做UI更新。如果您不确定,可以使用isDispatchThread 来检查您当前的代码是否在事件调度线程中运行。

【讨论】:

  • 好吧,我猜,如果我们不确定,我们可以使用 EventQueue.isDispatchThread() 方法来检查当前线程是否是事件调度线程。对吗?
  • 没错。我在答案中添加了有关此方法的一些信息。
  • 但是还是没有捷径?我肯定会喜欢上述样板的快捷方式或宏(如果 isDispatchThread 执行 X,否则包装 X 并挂起它。)。来自德尔福,我想把整个事情都称为Sync( x(a,b,c) ),但我想java语法是java语法,public void {}的东西是不可避免的。对我来说很有趣的是,我发现自己希望使用 C 风格的宏来避免编写 Java,因为它的设计目的是编写。
【解决方案2】:

仅当您尚未在事件调度线程上时才需要执行此操作。除非您已经从主线程启动了新线程或执行了代码,否则您的所有代码可能已经从事件分派线程运行,因此没有必要这样做。例如,所有 UI 事件处理程序都在事件调度线程上调用,因此您不需要对从那里调用的代码执行此操作。

【讨论】:

    【解决方案3】:

    您可以使用 Eclipse 的模板功能,而不是真正避免“重复”(java 人可能会说,可读的代码没有很多秘密)。我将其设置为将两个字母“il”扩展为以下块:

    EventQueue.invokeLater(new Runnable() {
                public void run() {
                    try {
                        // do something.
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
    

    显然这种调度队列设计不仅是推荐的,它基本上是必需的。这可能是我见过的将 lambda 推入消息队列的任何语言中最吵闹的方式。但它就在那里。这是java。在 Java 的辩护中,从上面的内容中可以清楚地看出到底发生了什么。我确实讨厌打字的数量,但我能想到的唯一能避免它的是 C 预处理器宏,我敢打赌 Java 人不喜欢使用这些。通过模板进行代码扩展更具可读性、可支持性,并且不涉及任何黑魔法。

    【讨论】:

    • P 不,不,永远不要使用 try - catch - finally 来构建 GUI,也不要在 invokeLater 中使用 :-)
    • @mKorbel 你能解释一下原因吗?
    • 我认为您对已检查的异常别无选择。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-03
    • 2011-11-18
    • 2012-07-31
    • 2010-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多