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?

Community
  • 1
  • 1
11684
  • 7,356
  • 12
  • 48
  • 71
  • 4
    "What does invokeLater() do?" is answered in the SwingUtilities javadoc page, as you might expect. – slim Aug 22 '12 at 16:14
  • 1
    [Java Swing & Concurrency Tutorial](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html). – assylias Aug 22 '12 at 16:17

3 Answers3

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...

Kumar Vivek Mitra
  • 33,294
  • 6
  • 48
  • 75
  • 4
    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 ;-) – kleopatra Aug 22 '12 at 16:24
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.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
  • 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. – assylias Aug 22 '12 at 16:16
  • 1
    not only changes - each and every _access_ (including instantiation) must be on the EDT – kleopatra Aug 22 '12 at 16:19
  • 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 [here](http://weblogs.java.net/blog/alexfromsun/archive/2006/02/debugging_swing.html) – Robin Aug 22 '12 at 16:31
  • 1
    @assylias and Robin, thanks for the correction. I work both with Swing and with SWT/JFace and I mixed them up. – Marko Topolnik Aug 22 '12 at 16:35
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).

nullpotent
  • 9,162
  • 1
  • 31
  • 42
  • 2
    Most of the time, you're doing everything from `a thread`. Do you mean `not the main thread`? – 11684 Aug 22 '12 at 16:17
  • 6
    -1 for the _nothing bad_ (unfortunately out off votes for today ;-) Please edit your answer to properly explain what you really mean. – kleopatra Aug 22 '12 at 16:20
  • 1
    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? – 11684 Aug 22 '12 at 16:23
  • @11684 Yes you should, unless you know that you already are in the EDT. – assylias Aug 22 '12 at 16:24
  • @assylias how would I know that? – 11684 Aug 22 '12 at 16:24
  • Found it, `public static boolean isEventDispatchThread()`. – 11684 Aug 22 '12 at 16:25
  • 1
    @11684 however even if you *are* in the EDT, invokeLater will still work, so you might as well use it. – slim Aug 22 '12 at 16:27
  • @11684 [This post](http://stackoverflow.com/a/7863399/829571) gives hints. – assylias Aug 22 '12 at 16:27
  • "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. – Steve Kuo Aug 23 '12 at 00:15