It is often useful for a background task to provide interim results while it is still working. The task can do this by invokingSwingWorker.publish
. This method accepts a variable number of arguments. Each argument must be of the type specified bySwingWorker
's second type parameter.To collect results provided by
publish
, overrideSwingWorker.process
This method will be invoked from the event dispatch thread. Results from multiple invocations ofpublish
are often accumulated for a single invocation ofprocess
.Let's look at the way the
example uses
Flipper
publish
to provide interim results. This program tests the fairness ofjava.util.Random
by generating a series of randomboolean
values in a background task. This is equivalent to flipping a coin; hence the nameFlipper
. To report its results, the background task uses an object of typeFlipPair
Theprivate static class FlipPair { private final long heads, total; FlipPair(long heads, long total) { this.heads = heads; this.total = total; } }heads
field is the number of times the random value has beentrue
; thetotal
field is the total number of random values.The background task is represented by an instance of
FlipTask
:Since the task does not return a final result, it does not matter what the first type parameter is;private class FlipTask extends SwingWorker<Void, FlipPair> {Void
is used as a placeholder. The task invokespublish
after each "coin flip":(The@Override protected Void doInBackground() { long heads = 0; long total = 0; Random random = new Random(); while (!isCancelled()) { total++; if (random.nextBoolean()) { heads++; } publish(new FlipPair(heads, total)); } return null; }isCancelled
method is discussed in the next section.) Becausepublish
is invoked very frequently, a lot ofFlipPair
values will probably be accumulated beforeprocess
is invoked in the event dispatch thread;process
is only intested in the last value reported each time, using it to update the GUI:Ifprotected void process(Listpairs) { FlipPair pair = pairs.get(pairs.size() - 1); headsText.setText(String.format("%d", pair.heads)); totalText.setText(String.format("%d", pair.total)); devText.setText(String.format("%.10g", ((double) pair.heads)/((double) pair.total) - 0.5)); } Random
is fair, the value displayed indevText
should get closer and closer to 0 asFlipper
runs.
Note: ThesetText
method used inFlipper
is actually "thread safe" as defined in its specification. That means that we could dispense withpublish
andprocess
and set the text fields directly from the worker thread. We've chosen to ignore this fact in order to provide a simple demonstration ofSwingWorker
interim results.