Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

invokeAndWait method in SwingUtilities

Tags:

java

swing

Please explain invokeAndWait() method in SwingUtilities.I am unable to understand this. Explain it very clearly. It would be of great help if you try out with an example.

Edited to add @noob's expansion of the question:

What's not clear about this?

Here's a modified usage example:

import javax.swing.SwingUtilities;

public class InvokeAndWaitStuff 
{
    public static void main(String[] args)
    {
        final Runnable doHelloWorld = new Runnable() {
             public void run() {
                 System.out.println("Hello World on " + Thread.currentThread());
             }
         };

         Thread appThread = new Thread() {
             public void run() {
                 try {
                     SwingUtilities.invokeAndWait(doHelloWorld);
                 }
                 catch (Exception e) {
                     e.printStackTrace();
                 }
                 System.out.println("Finished on " + Thread.currentThread());
             }
         };
         appThread.start();
    }
}

Output:

Hello World on Thread[AWT-EventQueue-0,6,main]
Finished on Thread[Thread-0,5,main]

And why is this important?:

Causes doHelloWorld.run() to be executed synchronously on the AWT event dispatching thread. This call blocks until all pending AWT events have been processed and (then) doHelloWorld.run() returns. This method should be used when an application thread needs to update the GUI.

As far as I can tell, this is basically a bottleneck that forces GUI updates to be executed synchronously by a single thread, rather than asynchronously by multiple threads, which can potentially be unsafe.

like image 200
saplingPro Avatar asked Mar 31 '11 12:03

saplingPro


2 Answers

To understand what invokeAndWait() does, you first need to understand the event/thread model of Swing.

Basically, everything that affects the GUI in any way must happen on a single thread. This is because experience shows that a multi-threaded GUI is impossible to get right.

In Swing, this special GUI thread is called the Event Dispatch Thread, or EDT. It is started as soon as a Swing top-level component is displayed, and it's bascially a worker thread that has a FIFO queue of event objects that it executes one after another.

When a Swing GUI needs to be drawn or updated, the JRE places an event on the EDT queue. User actions that cause listeners to be called start as events on the EDT queue. And (this is this is the important part) everything your program does that changes the GUI (like registering listeners, adding/removing GUI components or changing model data that the GUI displays) must be placed in the EDT queue, or the GUI can get corrupted.

And now for the finish: invokeAndWait() places the Runnable you pass to it into the EDT event queue and waits until the EDT has executed it. This should be used when a non-GUI thread needs to do something that affects the GUI, but also needs to wait until it is actually done before it can continue. If you just want to do something that affects the GUI but do not care when it is finished, you should instead use invokeLater().

like image 180
Michael Borgwardt Avatar answered Oct 21 '22 09:10

Michael Borgwardt


I had a similar problem in a JTable. The program was blocked somewhere in "scrollRectToVisible" method. I have replaced the call by wrapping it in an invokeLater call. The invokeAndWait did not resolve my block problem.

    SwingUtilities.invokeLater(new Runnable() {          @Override         public void run() {             table.scrollRectToVisible(r);         }      }); 
like image 40
Burkhard Losch Avatar answered Oct 21 '22 09:10

Burkhard Losch