SwingWorker's
doInBackground and get methods
SwingWorker's publish and process methods
SwingWorker is unspecified and should not be relied on.
When writing a multi-threaded application using Swing, there are two constraints to keep in mind: (refer to Concurrency in Swing for more details):
These constraints mean that a GUI application with time intensive computing needs at least two threads: 1) a thread to perform the lengthy task and 2) the Event Dispatch Thread (EDT) for all GUI-related activities. This involves inter-thread communication which can be tricky to implement.
SwingWorker is designed for situations where you need to have a long
running task run in a background thread and provide updates to the UI
either when done, or while processing.
Subclasses of SwingWorker must implement
the doInBackground method to perform the background computation.
Workflow
There are three threads involved in the life cycle of a
SwingWorker :
Current thread: The execute method is
called on this thread. It schedules SwingWorker for the execution on a
worker
thread and returns immediately. One can wait for the SwingWorker to
complete using the get methods.
Worker thread: The doInBackground
method is called on this thread.
This is where all background activities should happen. To notify
PropertyChangeListeners about bound properties changes use the
firePropertyChange and
getPropertyChangeSupport methods. By default there are two bound
properties available: state and progress.
Event Dispatch Thread: All Swing related activities occur
on this thread. SwingWorker invokes the
process and done methods and notifies
any PropertyChangeListeners on this thread.
Often, the Current thread is the Event Dispatch Thread.
Before the doInBackground method is invoked on a worker thread,
SwingWorker notifies any PropertyChangeListeners about the
state property change to StateValue.STARTED. After the
doInBackground method is finished the done method is
executed. Then SwingWorker notifies any PropertyChangeListeners
about the state property change to StateValue.DONE.
SwingWorker is only designed to be executed once. Executing a
SwingWorker more than once will not result in invoking the
doInBackground method twice.
Sample Usage
The following example illustrates the simplest use case. Some processing is done in the background and when done you update a Swing component.
Say we want to find the "Meaning of Life" and display the result in
a JLabel.
final JLabel label;
class MeaningOfLifeFinder extends SwingWorker<String, Object> {
@Override
public String doInBackground() {
return findTheMeaningOfLife();
}
@Override
protected void done() {
try {
label.setText(get());
} catch (Exception ignore) {
}
}
}
(new MeaningOfLifeFinder()).execute();
The next example is useful in situations where you wish to process data as it is ready on the Event Dispatch Thread.
Now we want to find the first N prime numbers and display the results in a
JTextArea. While this is computing, we want to update our
progress in a JProgressBar. Finally, we also want to print
the prime numbers to System.out.
class PrimeNumbersTask extends
SwingWorker<List<Integer>, Integer> {
PrimeNumbersTask(JTextArea textArea, int numbersToFind) {
//initialize
}
@Override
public List<Integer> doInBackground() {
while (! enough && ! isCancelled()) {
number = nextPrimeNumber();
publish(number);
setProgress(100 * numbers.size() / numbersToFind);
}
}
return numbers;
}
@Override
protected void process(List<Integer> chunks) {
for (int number : chunks) {
textArea.append(number + "\n");
}
}
}
JTextArea textArea = new JTextArea();
final JProgressBar progressBar = new JProgressBar(0, 100);
PrimeNumbersTask task = new PrimeNumbersTask(textArea, N);
task.addPropertyChangeListener(
new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
progressBar.setValue((Integer)evt.getNewValue());
}
}
});
task.execute();
System.out.println(task.get()); //prints all prime numbers we have got
Because SwingWorker implements Runnable, a
SwingWorker can be submitted to an
java. for execution.
| Modifier and Type | Class and Description |
|---|---|
| private static class | |
| public static enum | SwingWorker.
Values for the |
| private class |
| Modifier and Type | Field and Description |
|---|---|
| private AccumulativeRunnable | doNotifyProgressChange
handler for progress property change notifications. |
| private AccumulativeRunnable | doProcess
Handler for |
| private final AccumulativeRunnable | |
| private static ExecutorService | |
| private final FutureTask | future
Everything is run inside this FutureTask. |
| private static final int | MAX_WORKER_THREADS
number of worker threads. |
| private volatile int | progress
current progress. |
| private final PropertyChangeSupport | propertyChangeSupport
all propertyChangeSupport goes through this. |
| private volatile SwingWorker. | state
current state. |
| Access | Constructor and Description |
|---|---|
| public |
| Modifier and Type | Method and Description |
|---|---|
| public final void | addPropertyChangeListener(PropertyChangeListener
the listener)PropertyChangeListener to be addedAdds a |
| public final boolean | cancel(boolean mayInterruptIfRunning)
Implements java. Attempts to cancel execution of this task. |
| protected abstract T | Returns: the computed resultComputes a result, or throws an exception if unable to do so. |
| protected void | |
| private void | |
| public final void | |
| public final void | firePropertyChange(String
the programmatic name of the property that was
changed propertyName, Object the old value of the property oldValue, Object the new value of the property newValue)Reports a bound property update to any registered listeners. |
| public final T | get()
Implements java. Waits if necessary for the computation to complete, and then retrieves its result. |
| public final T | get(long timeout, TimeUnit unit)
Implements java. Waits if necessary for at most the given time for the computation to complete, and then retrieves its result, if available. |
| public final int | |
| public final PropertyChangeSupport | Returns: PropertyChangeSupport for this SwingWorkerReturns the |
| public final SwingWorker. | |
| private static synchronized ExecutorService | Returns: ExecutorService for theSwingWorkersreturns workersExecutorService. |
| public final boolean | isCancelled()
Implements java. Returns |
| public final boolean | |
| protected void | |
| protected final void | |
| public final void | removePropertyChangeListener(PropertyChangeListener
the listener)PropertyChangeListener to be removedRemoves a |
| public final void | run()
Implements java. Sets this |
| protected final void | |
| private void |
| doNotifyProgressChange | back to summary |
|---|---|
| private AccumulativeRunnable<Integer> doNotifyProgressChange handler for progress property change notifications. | |
| doProcess | back to summary |
|---|---|
| private AccumulativeRunnable<V> doProcess Handler for | |
| doSubmit | back to summary |
|---|---|
| private final AccumulativeRunnable<Runnable> doSubmit | |
| executorService | back to summary |
|---|---|
| private static ExecutorService executorService | |
| future | back to summary |
|---|---|
| private final FutureTask<T> future Everything is run inside this FutureTask. Also it is used as a delegate for the Future API. | |
| MAX_WORKER_THREADS | back to summary |
|---|---|
| private static final int MAX_WORKER_THREADS number of worker threads. | |
| progress | back to summary |
|---|---|
| private volatile int progress current progress. | |
| propertyChangeSupport | back to summary |
|---|---|
| private final PropertyChangeSupport propertyChangeSupport all propertyChangeSupport goes through this. | |
| state | back to summary |
|---|---|
| private volatile SwingWorker. current state. | |
| SwingWorker | back to summary |
|---|---|
| public SwingWorker() Constructs this | |
| addPropertyChangeListener | back to summary |
|---|---|
| public final void addPropertyChangeListener(PropertyChangeListener listener) Adds a Note This is merely a convenience wrapper. All work is delegated to
| |
| cancel | back to summary |
|---|---|
| public final boolean cancel(boolean mayInterruptIfRunning) Implements java. Doc from java. Attempts to cancel execution of this task. This method has no
effect if the task is already completed or cancelled, or could
not be cancelled for some other reason. Otherwise, if this
task has not started when The return value from this method does not necessarily
indicate whether the task is now cancelled; use | |
| doInBackground | back to summary |
|---|---|
| protected abstract T doInBackground() throws Exception Computes a result, or throws an exception if unable to do so. Note that this method is executed only once. Note this method is executed in a background thread.
| |
| done | back to summary |
|---|---|
| protected void done() Executed on the Event Dispatch Thread after the
| |
| doneEDT | back to summary |
|---|---|
| private void doneEDT() Invokes | |
| execute | back to summary |
|---|---|
| public final void execute() Schedules this Note
| |
| firePropertyChange | back to summary |
|---|---|
| public final void firePropertyChange(String propertyName, Object oldValue, Object newValue) Reports a bound property update to any registered listeners. No event is
fired if
This
When called off the Event Dispatch Thread
Note This is merely a convenience wrapper. All work is delegated to
| |
| get | back to summary |
|---|---|
| public final T get() throws InterruptedException, ExecutionException Implements java. Doc from java. Waits if necessary for the computation to complete, and then retrieves its result. Note calling
When you want the For example:
class SwingWorkerCompletionWaiter implements PropertyChangeListener {
private JDialog dialog;
public SwingWorkerCompletionWaiter(JDialog dialog) {
this.dialog = dialog;
}
public void propertyChange(PropertyChangeEvent event) {
if ("state".equals(event.getPropertyName())
&& SwingWorker.StateValue.DONE == event.getNewValue()) {
dialog.setVisible(false);
dialog.dispose();
}
}
}
JDialog dialog = new JDialog(owner, true);
swingWorker.addPropertyChangeListener(
new SwingWorkerCompletionWaiter(dialog));
swingWorker.execute();
//the dialog will be visible until the SwingWorker is done
dialog.setVisible(true);
| |
| get | back to summary |
|---|---|
| public final T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException Implements java. Doc from java. Waits if necessary for at most the given time for the computation to complete, and then retrieves its result, if available.
Please refer to
| |
| getProgress | back to summary |
|---|---|
| public final int getProgress() Returns the
| |
| getPropertyChangeSupport | back to summary |
|---|---|
| public final PropertyChangeSupport getPropertyChangeSupport() Returns the
This Note The returned
| |
| getState | back to summary |
|---|---|
| public final SwingWorker. Returns the
| |
| getWorkersExecutorService | back to summary |
|---|---|
| private static synchronized ExecutorService getWorkersExecutorService() returns workersExecutorService. returns the service and creates it if necessary.
| |
| isCancelled | back to summary |
|---|---|
| public final boolean isCancelled() Implements java. Doc from java. Returns | |
| isDone | back to summary |
|---|---|
| public final boolean isDone() Implements java. Doc from java. Returns | |
| process | back to summary |
|---|---|
| protected void process(List<V> chunks) Receives data chunks from the
Please refer to the | |
| publish | back to summary |
|---|---|
| protected final void publish(V... chunks) Sends data chunks to the
Because the For example:
publish("1");
publish("2", "3");
publish("4", "5", "6");
might result in:
process("1", "2", "3", "4", "5", "6")
Sample Usage. This code snippet loads some tabular data and
updates
class TableSwingWorker extends
SwingWorker<DefaultTableModel, Object[]> {
private final DefaultTableModel tableModel;
public TableSwingWorker(DefaultTableModel tableModel) {
this.tableModel = tableModel;
}
| |
| removePropertyChangeListener | back to summary |
|---|---|
| public final void removePropertyChangeListener(PropertyChangeListener listener) Removes a Note This is merely a convenience wrapper. All work is delegated to
| |
| run | back to summary |
|---|---|
| public final void run() Implements java. Sets this | |
| setProgress | back to summary |
|---|---|
| protected final void setProgress(int progress) Sets the
Because For example, the following invocations: setProgress(1); setProgress(2); setProgress(3);might result in a single PropertyChangeListener notification with
the value 3.
| |
| setState | back to summary |
|---|---|
| private void setState(SwingWorker. Sets this
| |
| Modifier and Type | Field and Description |
|---|---|
| private static final int |
| Access | Constructor and Description |
|---|---|
| private |
| Modifier and Type | Method and Description |
|---|---|
| public void | actionPerformed(ActionEvent event)
Implements java. Invoked when an action occurs. |
| protected void | run(List<Runnable> args)
Implements abstract sun. Equivalent to |
| protected void | submit()
Overrides sun. Sends this
This method is to be executed only from |
| DELAY | back to summary |
|---|---|
| private static final int DELAY | |
| DoSubmitAccumulativeRunnable | back to summary |
|---|---|
| private DoSubmitAccumulativeRunnable() | |
| actionPerformed | back to summary |
|---|---|
| public void actionPerformed(ActionEvent event) Implements java. Doc from java. Invoked when an action occurs. | |
| run | back to summary |
|---|---|
| protected void run(List<Runnable> args) Implements abstract sun. Doc from sun. Equivalent to
| |
| submit | back to summary |
|---|---|
| protected void submit() Overrides sun. Doc from sun. Sends this
This method is to be executed only from
This implementation uses
| |
state bound property.
| Modifier and Type | Field and Description |
|---|---|
| public static final SwingWorker. | DONE
|
| public static final SwingWorker. | PENDING
Initial |
| public static final SwingWorker. | STARTED
|
| Access | Constructor and Description |
|---|---|
| private |
| Modifier and Type | Method and Description |
|---|---|
| public static SwingWorker. | |
| public static SwingWorker. |
| DONE | back to summary |
|---|---|
| public static final SwingWorker.
| |
| PENDING | back to summary |
|---|---|
| public static final SwingWorker. Initial | |
| STARTED | back to summary |
|---|---|
| public static final SwingWorker.
| |
| StateValue | back to summary |
|---|---|
| private StateValue() | |
| valueOf | back to summary |
|---|---|
| public static SwingWorker. | |
| values | back to summary |
|---|---|
| public static SwingWorker. | |
| Access | Constructor and Description |
|---|---|
| pack-priv |
| Modifier and Type | Method and Description |
|---|---|
| public void | firePropertyChange(final PropertyChangeEvent evt)
Overrides java. Fires a property change event to listeners that have been registered to track updates of all properties or a property with the specified name. |
| SwingWorkerPropertyChangeSupport | back to summary |
|---|---|
| pack-priv SwingWorkerPropertyChangeSupport(Object source) | |
| firePropertyChange | back to summary |
|---|---|
| public void firePropertyChange(final PropertyChangeEvent evt) Overrides java. Doc from java. Fires a property change event to listeners that have been registered to track updates of all properties or a property with the specified name. No event is fired if the given event's old and new values are equal and non-null.
| |