I have a task that when done it update a swing GUI telling that is done. What I saw is that you can use done()
method or attach a PropertyChangeListener
and listen for the change to done
status.
What is better to use and why? Or are they the same?
For example, this:
public class Foo implements PropertyChangeListener {
public void propertyChange(PropertyChangeEvent evt) {
if ("state".equals(evt.getPropertyName())
&& (SwingWorker.StateValue.DONE.equals(evt.getNewValue()))) {
this.updateTheGuiAndOtherThings();
}
}
}
or this:
public class W extends SwingWorker {
protected Boolean doInBackground() throws Exception {...}
protected void done() {
otherClass.updateTheGuiAndOtherThings();
}
}
In my case isn't necessary better efficiency, I ask more for correct code writing.
A change listener is similar to a property change listener. A change listener is registered on an object — typically a component, but it could be another object, like a model — and the listener is notified when the object has changed.
Since Swing is not thread-safe by design, it's designer did provide couple of utility methods in SwingUtilities class to update any Swing component from a thread other thread Event Dispatcher Thread. You can use invokeAndWait() and invokeLater() to update a Swing component from any arbitrary thread.
An invokeLater() method is a static method of the SwingUtilities class and it can be used to perform a task asynchronously in the AWT Event dispatcher thread. The SwingUtilities. invokeLater() method works like SwingUtilities. invokeAndWait() except that it puts the request on the event queue and returns immediately.
Important Methods of SwingWorker. Attempts to cancel the execution of this task. This attempt will fail if the task has already been completed, has already been canceled, or could not be canceled for some other reason. If successful, and this task has not started when cancel is called, this task should never run.
Is it better to use done method or a change listener on SwingWorker?
Generally speaking both ways are correct and equivalent.
However the main advantage of using PropertyChangeListener
is you can have several listeners attached to the SwingWorker which allows you to split tasks in small code units rather than have a single done()
block of code. This is useful for example if you have to update several Swing components and you want to keep those updates cohesively separate.
In addition using listeners reduces coupling between the SwingWorker and GUI components: it has no knowledge about what will happen when the background thread finishes and it's ok. By overriding done()
method this won't be true anymore.
An important thing to do - when either listening for StateValue.DONE
or overriding done()
method - is to call get()
method in order to catch and treat any exception that may be thrown during doInBackground()
processing. See this Q&A related to this point.
For the rest there is no major difference. I'd go with listeners just for scalability.
Based on @mKorbel's comments below, you might want to take a look to this topic too: Is a swingWorker guaranteed to throw a state property change event on completion? and also even recosinder use a SwingWorker. I have had no problems personally but it's good to be aware about possible bugs related to the multi-threading nature of this matter.
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