I cannot really get the advantage of using a swingworker instead of just simply putting the heavy task in a (simple) background-thread.
This is just a codesnippet but shows the task of counting an integer and putting the values in a JLabel. (this is within the ActionPerformed)
Thread t = new Thread() {
public void run() {
for (int i = 0; i < 2000000; i++) {
counter++;
label.setText(Integer.toString(counter));
}
}
};
t.start();
Instead of this simple codesnippet I have been told to use the abstract SwingWorker-class and override methods such as doInBackground, process and done.
It works very fine when the label is updating simply using Thread. Why should I create a new class that extends swingworker and implement the abstract methods? I can at the moment only think of the Swing-worker as threadsafe, is that the answer?
Swing is not thread safe, modifying the UI outside of the context of the EDT, like you are will, cause random paint artifacts and dirty paint issues which will be near impossible to track down.
See Concurrency in Swing for more details
The publish
method of the SwingWorker
pushes the update onto the a queue, which is processed within the EDT and pushed to the process
method. done
is also called within the context of the EDT, making it safe to update the UI from
Now, you could use something like...
Thread t = new Thread() {
public void run() {
int counter = 0 ;
for (int i = 0; i < 2000000; i++) {
counter++;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
label.setText(Integer.toString(counter));
}
});
}
}
};
t.start();
And under Java 8+ you probably won't have to many issues, but Java 6 can be finicky about needing a final
variable for anonymous classes, which is why I generally avoid it.
SwingWoker
also has progress support via it's setProgress
method and PropertyChangeListener
, which is also another way you can provide feedback...