I have a couple of questions with regards to Swing and using EDT for GUI updates. I just started reading on this stuff so I am a full beginner in this area:
SwingUtilities.invokeLater
we enqueue it to the current queue of GUI update tasks (the EDT) right? How exactly does the SwingWorker ensure that done()
method is run on EDT? It sets the following code:
future = new FutureTask<T>(callable) { @Override protected void done() { doneEDT(); setState(StateValue.DONE); } };
so I was wondering whether FutureTask somehow makes sure that invokeLater
is called?
Thanks for all your answers.
RepaintManager
to detect most of these violations: see this article . actionPerformed
of the corresponding Action
or ActionListener
will be called on the EDT. invokeLater
call simply adds the Runnable
at the end of the queue. Using invokeLater
a second time a bit later will add this new Runnable
after the previously scheduled Runnable
. Take a look at the code for doneEDT
private void doneEDT() { Runnable doDone = new Runnable() { public void run() { done(); } }; if (SwingUtilities.isEventDispatchThread()) { doDone.run(); } else { doSubmit.add(doDone); } }
doneEDT()
method has the following comment: Invokes done on the EDT . SwingWorker ensure that done() method is run on EDT via below code:
Runnable doDone =
new Runnable() {
public void run() {
done();
}
};
if (SwingUtilities.isEventDispatchThread()) {
doDone.run();
} else {
doSubmit.add(doDone);
}
Actually it add the doDone variable into AccumulativeRunnable doSubmit,
See the source code of AccumulativeRunnable.java you will find there has a below code
protected void submit() {
SwingUtilities.invokeLater(this);
}
That's why swingworker ensure the method done() running on EDT
1. In Java GUI applications, main()
method is not long lived, after scheduling the construction of GUI in the Event Dispatcher Thread
, the main()
method quits...and Now its EDT's responsibility to handle the GUI.
2. So we don't need to start our app on the EDT, its automatically done.
3 Always keep the UI work on the UI thread, and Non-UI work on the Non-UI thread.
So Always keep your EDT thread, which is the GUI thread only for GUI work.
Eg:
public static void main(String[] args){
EventQueue.invokeLater(new Runnable(){
public void run(){
myframe.setVisible(true);
}
}
}
4. Create a separate Non-UI thread to handle that long time taking method.
5. You can simply use a Thread
or use SwingWorker
which is specially introduced into Java to sync the UI and Non-UI thread.
6. SwingWorker doesnt ensure that done() method is run on EDT, but sync the output of it to EDT thread, which is the GUI thread.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.