我们是否应该在Java桌面应用程序中使用EventQueue.invokeLater进行任何GUI更新?

时间:2022-09-13 00:14:44

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?

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

3 个解决方案

#1


27  

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

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

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 another thread 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 isDispatchThread to check whether your current code is running inside the event dispatch thread.

因此在很多情况下,您不需要invokeLater,您可以直接进行UI更新。如果您不确定,可以使用isDispatchThread检查当前代码是否在事件派发线程内运行。

#2


2  

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事件处理程序,因此您不需要为从那里调用的代码执行此操作。

#3


1  

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:

而不是真正避免“重复”(java人可能会说,没有很多秘密的可读代码),你可以使用Eclipse的模板功能。我已将它设置为将两个字母“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。而在Java的辩护中,从上面的确切情况来看,这显然是正在发生的事情。我不满意打字的数量,但我唯一能想到的就是避免它是C预处理器宏,我敢打赌Java人不喜欢使用它们。通过模板进行代码扩展更具可读性,可支持性,并且不涉及任何黑魔法。

#1


27  

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

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

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 another thread 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 isDispatchThread to check whether your current code is running inside the event dispatch thread.

因此在很多情况下,您不需要invokeLater,您可以直接进行UI更新。如果您不确定,可以使用isDispatchThread检查当前代码是否在事件派发线程内运行。

#2


2  

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事件处理程序,因此您不需要为从那里调用的代码执行此操作。

#3


1  

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:

而不是真正避免“重复”(java人可能会说,没有很多秘密的可读代码),你可以使用Eclipse的模板功能。我已将它设置为将两个字母“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。而在Java的辩护中,从上面的确切情况来看,这显然是正在发生的事情。我不满意打字的数量,但我唯一能想到的就是避免它是C预处理器宏,我敢打赌Java人不喜欢使用它们。通过模板进行代码扩展更具可读性,可支持性,并且不涉及任何黑魔法。