我们应该使用 EventQueue.invokeLater 来更新 Java 桌面应用程序中的任何 GUI 吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3541373/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 02:18:58  来源:igfitidea点击:

Should we use EventQueue.invokeLater for any GUI update in a Java desktop application?

javaswingthread-safety

提问by nash

I know that by using this method, the runnable parameter is submitted to the system EventQueue. But should all GUI updates be done this using this method? I mean, if i want to say, change a text of JButton, should i use something like this:

我知道通过使用这种方法,runnable 参数被提交到系统EventQueue。但是是否应该使用这种方法来完成所有 GUI 更新?我的意思是,如果我想说,更改 JButton 的文本,我应该使用以下内容:

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

If i should use this approach, any pattern we can use to avoid this repetitive code?

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

回答by Ronald Wildenberg

You only need to use invokeLaterwhen you want to update your UI from another thread that is not the UI thread (event dispatch thread).

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

Suppose you have a handler for a button-click and you want to change the text of a label when someone clicks the button. Then it's perfectly save to set the label text directly. This is possible because the handler for the button-click event runs in the UI thread.

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

Suppose, however, that on another button-click you start anotherthread that does some work and after this work is finished, you want to update the UI. Then you use invokeLater. This method ensures that your UI update is executed on the UI thread.

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

So in a lot of cases, you do not need invokeLater, you can simply do UI updates directly. If you're not sure, you can use isDispatchThreadto check whether your current code is running inside the event dispatch thread.

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

回答by Ramon

You need to do this only if you're not already on the event dispatch thread. Unless you've started new threads or executed code from the main thread all your code probably already runs from the event dispatch thread making this unnecessary. For example, all the UI event handlers are called on the event dispatch thread so you would not need to do that for code called from there.

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

回答by Warren P

Instead of truly avoiding "repetitive" (java people would probably say, readable code without many secrets) you could use Eclipse's templates feature. i have it set to expand the two letters "il" to the following block:

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

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

Apparently this dispatch queue design is not only recommended, it's basically required. This is perhaps the noisiest way I've ever seen in any language of pushing a lambda off into a message queue. But there it is. This is java. And in Java's defence, it's certainly obvious from the above exactly what's going on. I do resent the amount of typing, but the only thing I can think of that would avoid it is C preprocessor Macros, and I bet Java people don't like using those. Code expansion via templates is more readable, supportable, and doesn't involve any black magic.

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