Explain what the following code does?
Asked Answered
A

5

15
java.awt.EventQueue.invokeLater(new Runnable() {
    public void run() {
        new NewJFrame().setVisible(true);
    }
});

Please tell me what does the above code does actually. I am looking for line by line explanation. especially the first line and tell me why do we use that and in what scenarios we have to use this.

Americaamerican answered 5/2, 2011 at 18:42 Comment(0)
M
28

In this Example you see an anyonmous class that derives from Runnable. This anonymous class overrides the run method of the interface runnable. Then this anonymous class is instantiated and passed to the EventQueue.invokeLater method, which is a static method. This method appends the object into... well... the eventQueue. In the EvenQueue are many events, like keyboard events or mouse events or whatever. There is a Thread that continuesly polls data from this queue. Once that Thread reaches the anonymous class that was instantiated here, it will execute the run() method, which will instantiate an Object of class NewJFrame and set it to be visible.

The whole point of doing this this complicated is that the new JFrame().setVisible(true) part is not executed in the main thread, but in the event dispatching thread. In Swing you must execute all code that modifies the user interface in the event dispatching thread.

Mullinax answered 5/2, 2011 at 18:50 Comment(4)
And what would happen if you just put this in the main method, without any wrapping? public static void main(String args[]) {New JFrame().setVisible(true);}Balancer
@Martin: Then you break the rule that code that affects the UI must be executed in the event dispatching thread. This might happen to work (most of the times), but could also cause a number of errors related to race conditions etc. It is hard to predict what might happen. Maybe you run into drawing errors, maybe not.Mullinax
So if I understood correctly, it's a coding guideline, the best practice, but not a strict rule? I any case, thanx for the answer!Balancer
@Martin: No. It is a rule. If you break it, you risk random hard-to-debug problems. It's not like a best practice like "don't write all your code in a single line". That would create unreadable code, but theoretically works. Not adhering to the mentioned rule can break your application.Mullinax
T
4

Single-Thread-Model and EDT

Most modern UI libraries adopt the single-thread-model. That means, all the manipulation upon UI components MUST be done on the same single thread. Why? That's because allowing UI components being updated from multiple threads will lead to chaos since most Swing object methods are not "thread safe". For simplicity, efficiency and robustness, single-thread-model is adopted.

In Swing, the very thread that serve the single-thread-model is called the Event Dispatching Thread, i.e. EDT. It is not provided by Swing. It is provided by Abstract Window Toolkit, i.e. AWT.

Worker thread vs UI thread

A non-trivial GUI application usually has many threads. In modern GUI application, there can be many worker threads to do dirty work, but there's only one UI thread (Swing calls it EDT) to update the GUI. Worker threads usually need to reflect their work progress in GUI, so they need to communicate with the UI thread about that. So how does this communication happen?

java.awt.EventQueue

The communication happens through a message queue model. The java.awt.EventQueue is the very class that provides a event queue globally. This global event queue serves as the communication channel to the EDT. EDT picks up messages from this EventQueue and update UI components accordingly. If some other part of your program wants to manipulate the UI, that part of code should call EventQueue.invokeLater() or EventQueue.invokeAndWait() to queue a message into EventQueue. EDT will process all the pending messages in the EventQueue and eventually get to the message.

the main thread

Your code snippet usually resides in the main() thread, the main thread can be viewed as some kind of a worker thread here. Only that instead of updating the GUI by posting messages to EventQueue, it initiates the GUI. Anyway, initiation can be viewed as a kind of work, too.

After the GUI is initiated, the main thread will exits and the EDT will prevent the process from exiting.

And another good explanation:

Java Event-Dispatching Thread explanation

An interesting article: Multi-threaded toolkit, a failed dream?

Twist answered 16/6, 2016 at 2:44 Comment(1)
Looks like your last link there rotted or was misplaced? Do you have the link for that article? Sounds interesting.Trentontrepan
W
2

This is a block of code that is instructed to execute at a later time (sometimes called a deferred). The inner class (new Runnable() {...}) is essentially allowing you to pass a block of code that will be run. The invokeLater method guarantees that the block of code will be run, but makes no guarantees of when. Sometimes it's not safe to have certain code run immediately, and its too verbose to do the multi-threading yourself. So Java provides this utility method to safely run the code. The code will be run very soon, but not until it's safe to do so.

Workshop answered 5/2, 2011 at 18:52 Comment(0)
Z
1

The invokeLater call will put the specified runnable on a queue to be processed later. That is, the code inside the run() method will not have been run yet when the invokeLater method call returns.

There are two typical use-cases for this type of code.

  1. The currently executing code is run in a background thread. Background threads cannot access most of the swing API. Read more here for the reason for this. If the current thread is already the UI thread there is no reason and the call can safely be removed.
  2. The current block must be exited, ie the code reach the last brace. This may cause resources to be released and so on. This is not so common.

An anonymous class is passed as parameter to the invokeLater call. It is the same as this code.

private void foo()
{
  java.awt.EventQueue.invokeLater(new JFrameCreator());
}
private class JFrameCreator implements Runnable
{
  public void run() {
    new NewJFrame().setVisible(true);
  }
}
Zygotene answered 5/2, 2011 at 18:58 Comment(7)
thats a good explanation.. just tel me why do we use runnable() here ??Americaamerican
and i guess (new JFrameCreator()) will create a anonymous class. Does that mean that when this thread is processed the run() gets executed automatically. I am sorry if i am asking something completely wrong.. I just want to know about run() and (new JFrameCreator())..Americaamerican
No, sorry, but this won't work. The class JFrameCreator MUST implement Runnable (just write class JFrameCreator implements Runnable). And @Deepak: No, there is no anonymous class involved in this example.Mullinax
@yankee: only if the class JFrameCreator is implemented as runnable the run() method is invoked rite ? or what if we give a constructor for JFrameCreator and inside the constructor we call setVisible(true) ?? will that work ?Americaamerican
@Deepak: Well yeah it will not call the run() method. Because this code won't even compile. The invokeLater() method expects to get an Object that implements Runnable. It's just in the arguments list of that method. If you try to pass something else, then it won't compile. This way the invokeLater method makes sure that every object it gets HAS a method called run. / About the constructor part. No, will still not compile. And even if it would: The compiler is executed in the current thread. Thus yes, the code in the constructor would be executed, but in the main threadMullinax
@yankee: okay that is just perfect. I got a good picture of what is happening with runnable() and invokeLater(). thanks..Americaamerican
@Mullinax yeah, thanks. forgot the crucial "implements Runnable" in the example. Well, seems you've sorted it all out now anyway.Zygotene
A
1

Source

The invokeLater() method takes a Runnable object as its parameter. It sends that object to the event-dispatching thread, which executes the run() method. This is why it's always safe for the run() method to execute Swing code.

-IvarD

Algid answered 3/5, 2011 at 10:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.