What is SwingUtilities.invokeLater [duplicate]
Asked Answered
H

3

15

Possible Duplicate:
What does SwingUtilities.invokeLater do?
SwingUtilities.invokeLater

I have seen this little piece of code hundreds of times:

public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          createAndShowGUI();
        }
    });
}

Now my question is: what does invokeLater() do? What kind of bad things will happen if I just create and show my GUI inside the main thread?

Humanoid answered 22/8, 2012 at 16:11 Comment(2)
"What does invokeLater() do?" is answered in the SwingUtilities javadoc page, as you might expect.Hanako
Java Swing & Concurrency Tutorial.Mahratta
R
2

Nothing bad will happen if you're updating it from the EDT while following guidelines.

That is...

If invokeLater is called from the event dispatching thread -- for example, from a JButton's ActionListener -- the doRun.run() will still be deferred until all pending events have been processed.

Source

If that isn't the case, invokeLater() is required.

It schedules a Runnable which will be executed on the EDT (event dispatching thread).

Ratel answered 22/8, 2012 at 16:15 Comment(9)
Most of the time, you're doing everything from a thread. Do you mean not the main thread?Humanoid
-1 for the nothing bad (unfortunately out off votes for today ;-) Please edit your answer to properly explain what you really mean.Waxwing
So if I put my code in invokeLater() that Runnable will be executed from the EDT and no 'weird behavior` (as stated by assylias) will be created? And what if I want to, say, update my JLabel's text? Should I officially put that in invokeLater() once again?Humanoid
@Humanoid Yes you should, unless you know that you already are in the EDT.Mahratta
@Mahratta how would I know that?Humanoid
Found it, public static boolean isEventDispatchThread().Humanoid
@Humanoid however even if you are in the EDT, invokeLater will still work, so you might as well use it.Hanako
@Humanoid This post gives hints.Mahratta
"Nothing bad" isn't totally true. From SwingUtils.invokeLater "If invokeLater is called from the event dispatching thread -- for example, from a JButton's ActionListener -- the doRun.run() will still be deferred until all pending events have been processed.". So doing so from the EDT will cause your Runnable to run later than you probably want it to.Sponsor
B
10

1. Event Dispatcher Thread is the GUI thread.

2. If you are talking about the main() method...then its not long lived in Java Gui. main() method after scheduling the construction of GUI in EDT quits, now its EDT that handles the GUI.

3. invokeLater means that this call will return immediately as the event is placed in Event Dispatcher Queue, and run() method will run asynchronously...

Breadstuff answered 22/8, 2012 at 16:17 Comment(1)
hmm ... please consider using technical vocabulary so we all can understand what you really mean (not long lived or run simultaneously are not, which implies being either wrong or ambigous ;-)Waxwing
S
5

Swing is not thread-safe and all changes to Swing objects must be performed within the Event Dispatch Thread. If you try to run your code outside it, you'll get unspecified behavior, which will probably become weird at some point.

In contrast, the SWT/JFace GUI framework that Eclipse uses asserts the correct thread on each public entry point.

Snuffbox answered 22/8, 2012 at 16:14 Comment(4)
"If you try to run your code outside it, you'll just get an exception since the invoking thread is checked before any further actions" ? Running UI stuff outside of the EDT might create weird behaviour but will not necessarily throw an exception.Mahratta
not only changes - each and every access (including instantiation) must be on the EDTWaxwing
That exception is only the case in JavaFX, where they finally included that check. You can have similar behavior in Swing by using a custom repaint manager, as explained hereSyringe
@Mahratta and Robin, thanks for the correction. I work both with Swing and with SWT/JFace and I mixed them up.Snuffbox
R
2

Nothing bad will happen if you're updating it from the EDT while following guidelines.

That is...

If invokeLater is called from the event dispatching thread -- for example, from a JButton's ActionListener -- the doRun.run() will still be deferred until all pending events have been processed.

Source

If that isn't the case, invokeLater() is required.

It schedules a Runnable which will be executed on the EDT (event dispatching thread).

Ratel answered 22/8, 2012 at 16:15 Comment(9)
Most of the time, you're doing everything from a thread. Do you mean not the main thread?Humanoid
-1 for the nothing bad (unfortunately out off votes for today ;-) Please edit your answer to properly explain what you really mean.Waxwing
So if I put my code in invokeLater() that Runnable will be executed from the EDT and no 'weird behavior` (as stated by assylias) will be created? And what if I want to, say, update my JLabel's text? Should I officially put that in invokeLater() once again?Humanoid
@Humanoid Yes you should, unless you know that you already are in the EDT.Mahratta
@Mahratta how would I know that?Humanoid
Found it, public static boolean isEventDispatchThread().Humanoid
@Humanoid however even if you are in the EDT, invokeLater will still work, so you might as well use it.Hanako
@Humanoid This post gives hints.Mahratta
"Nothing bad" isn't totally true. From SwingUtils.invokeLater "If invokeLater is called from the event dispatching thread -- for example, from a JButton's ActionListener -- the doRun.run() will still be deferred until all pending events have been processed.". So doing so from the EDT will cause your Runnable to run later than you probably want it to.Sponsor

© 2022 - 2024 — McMap. All rights reserved.