Let's say we have a long/heavy task that must run in background, and publish its progress or whatever to the GUI. I know that this publishing must happen on the event dispatch thread. That's why we use a SwingWorker
for the task.
So, what we do, is something like this:
public class WorkerTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
JLabel label = new JLabel();
frame.add(label);
startWorker(label);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
});
}
private static void startWorker(JLabel label) {
new SwingWorker<Integer, Integer>() {
@Override
protected Integer doInBackground() throws Exception {
for (int i = 0; i < 500; i++) {
publish(i);
Thread.sleep(500); //Simulate long task
}
return null;
}
@Override
protected void process(List<Integer> chunks) {
Integer integer = chunks.get(0);
label.setText(String.valueOf(integer));
}
}.execute();
}
}
My question is, how the above differs from this:
private static void startWorker(JLabel label) {
new SwingWorker<Integer, Integer>() {
@Override
protected Integer doInBackground() throws Exception {
for (int i = 0; i < 500; i++) {
int i2 = i;
SwingUtilities.invokeLater(() -> {
label.setText(String.valueOf(i2));
});
Thread.sleep(500); //Simulate long task
}
return null;
}
}.execute();
}
In both cases, the label.setText()
which is an update to the GUI, runs to the Event dispatch thread. How are they different?
Of course, the question stands also why should I implement a done()
method to the worker vs calling SwingUtilities.invokeLater
at the end of the doInBackground
method? Besides handling the exception possibly thrown in doInBackground
method.
Look at the javadoc for method
publish()
in classSwingWorker
.Calling
SwingUtilities.invokeLater()
directly from methoddoInBackground()
does not perform the coalescing – according to the code in your question. Perhaps you can think of a reason why the coalescing is necessary? Also refer to Tasks that Have Interim ResultsRegarding method
done()
in classSwingWorker
, that you also asked about, again I refer you to the javadocSo you don't have to override method
done()
. Personally, I usually add a property listener to mySwingWorker
object for handling tasks that I need to perform once the [SwingWorker
] task has completed. But of-course, YMMV.