My understanding is that if I start up another thread to perform some actions, I would need to SwingUtilities.invokeAndWait
or SwingUtilities.invokeLater
to update the GUI while I'm in said thread. Please correct me if I'm wrong.
What I'm trying to accomplish is relatively straightforward: when the user clicks submit, I want to (before performing any actions) disable the submit button, perform the action, and at the end of the action re-enable the button. My method to perform the action updates the GUI directly (displays results) when it gets the results back.
This action basically queries a server and gets some results back.
What I have so far is:
boolean isRunning = false;
synchronized handleButtonClick() {
if ( isRunning == false ) {
button.setEnabled( false );
isRunning = true;
doAction();
}
}
doAction() {
new Thread() {
try {
performAction(); // Concern A
} catch ( ... ) {
displayStackTrace( ... ); // Concern B
} finally {
SwingUtilities.invokeLater ( /* simple Runnable to enable button */ );
isRunning = false;
}
}
}
For both of my concerns above, do I would have to use SwingUtilities.invokeAndWait
since they both will update the GUI? All GUI updates revolve around updating JTextPane
. Do I need to in my thread check if I'm on EDT and if so I can call my code (regardless of whether it updates the GUI or not) and NOT use SwingUtilities.invokeAndWait
?
EDIT: Here is what I am doing now:
handleButtonClick() {
if ( isRunning == true )
return;
disable button;
SwingWorker task = new MyTask();
task.execute();
}
...inside MyTask
doInBackground() {
return performAction();
}
done() {
result = get();
enable button;
isRunning = false;
interpret result (do most of the GUI updates here);
}
While performAction()
does some GUI updates, I have wrapped those in:
if ( SwingUtil.isEDT() )
doGUIupdate()
else
SwingUtil.invokeLater( new Runnable() {
run() {
doGUIupdate();
}
} );
Hopefully this is a step in the right direction, please comment if you believe there are better ways to handle my situation.
No, Java Swing components are not thread-safe in Java.
This means that most Swing components are, technically, not threadsafe for multithreaded applications. Now don't panic: it's not as bad as it sounds because there is a plan. All event processing in AWT/Swing is handled by a single system thread using a single system event queue. The queue serves two purposes.
Swing is single-threaded.
Absolutely yes. Legacy swing applications are still supported and enhanced. There is no alternative for that.
In my opinion you should almost never use invokeAndWait()
. If something is going to take awhile that will lock your UI.
Use a SwingWorker
for this kind of thing. Take a look at Improve Application Performance With SwingWorker in Java SE 6.
You should consider using SwingWorker
since it will not block the UI thread, whereas both SwingUtilities
methods will execute on the EDT thread, thus blocking the UI.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With