Class Task<T,V>
- All Implemented Interfaces:
Runnable
,Future<T>
,RunnableFuture<T>
- Direct Known Subclasses:
LoadImageTask
SwingWorker
that represents an application
background task. Tasks add descriptive properties that can
be shown to the user, a new set of methods for customizing
task completion, support for blocking input to the GUI while
the Task is executing, and a TaskListener
that
enables one to monitor the three key SwingWorker methods:
doInBackground
, process
and done
.
When a Task completes, the final done
method invokes
one of succeeded
, cancelled
, interrupted
,
or failed
. The final done
method invokes
finished
when the completion method returns or throws
an exception.
Tasks should provide localized values for the title
,
description
, and message
properties in a
ResourceBundle for the Task subclass. A
ResourceMap
is
loaded automatically using the Task subclass as the
startClass
and Task.class the stopClass
.
This ResourceMap is also used to look up format strings used in
calls to message
, which is used to set
the message
property.
For example: given a Task called MyTask
defined like this:
class MyTask extends Taskinvalid input: '<'MyResultType, Void> {
protected MyResultType doInBackground() {
message("startMessage", getPlannedSubtaskCount());
// do the work ... if an error is encountered:
message("errorMessage");
message("finishedMessage", getActualSubtaskCount(), getFailureCount());
// .. return the result
}
}
Typically the resources for this class would be defined in the
MyTask ResourceBundle, @{code resources/MyTask.properties}:
title = My Task description = A task of mine for my own purposes. startMessage = Starting: working on %s subtasks... errorMessage = An unexpected error occurred, skipping subtask finishedMessage = Finished: completed %1$s subtasks, %2$s failures
Task subclasses can override resource values in their own ResourceBundles:
class MyTaskSubclass extends MyTask { } # resources/MyTaskSubclass.properties title = My Task Subclass description = An appropriate description # ... all other resources are inherited
Tasks can specify that input to the GUI is to be blocked while
they're being executed. The inputBlocker
property specifies
what part of the GUI is to be blocked and how that's accomplished.
The inputBlocker
is set automatically when an @Action
method that returns a Task specifies a Task.BlockingScope
value
for the block
annotation parameter. To customize the way
blocking is implemented you can define your own Task.InputBlocker
.
For example, assume that busyGlassPane
is a component
that consumes (and ignores) keyboard and mouse input:
class MyInputBlocker extends InputBlocker { BusyIndicatorInputBlocker(Task task) { super(task, Task.BlockingScope.WINDOW, myGlassPane); } protected void block() { myFrame.setGlassPane(myGlassPane); busyGlassPane.setVisible(true); } protected void unblock() { busyGlassPane.setVisible(false); } } // ... myTask.setInputBlocker(new MyInputBlocker(myTask));
All of the settable properties in this class are bound, i.e. a
PropertyChangeEvent is fired when the value of the property changes.
As with the SwingWorker
superclass, all
PropertyChangeListeners
run on the event dispatching thread.
This is also true of TaskListeners
.
Unless specified otherwise specified, this class is thread-safe. All of the Task properties can be get/set on any thread.
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic enum
Specifies to what extent the GUI should be blocked a Task is executed by a TaskService.static class
Specifies to what extent input to the Application's GUI should be blocked while this Task is being executed and provides a pair of methods,block
andunblock
that do the work of blocking the GUI.Nested classes/interfaces inherited from class javax.swing.SwingWorker
SwingWorker.StateValue
Nested classes/interfaces inherited from interface java.util.concurrent.Future
Future.State
-
Constructor Summary
ConstructorsConstructorDescriptionTask
(Application application) Construct aTask
with an empty (""
) resource name prefix, whose ResourceMap is the value ofApplicationContext.getInstance().getResourceMap(this.getClass(), Task.class)
.Task
(Application application, String resourcePrefix) Deprecated.Task
(Application application, ResourceMap resourceMap, String resourcePrefix) Deprecated. -
Method Summary
Modifier and TypeMethodDescriptionvoid
addTaskListener
(TaskListener<T, V> listener) Adds aTaskListener
to this Task.protected void
Called when this Task has been cancelled bySwingWorker.cancel(boolean)
.protected final void
done()
protected void
Called when an execution of this Task fails and anExecutionExecption
is thrown byget
.protected void
finished()
Called unconditionally (in afinally
clause) after one of the completion methods,succeeded
,failed
,cancelled
, orinterrupted
, runs.final Application
final ApplicationContext
Return the value of thedescription
property.long
getExecutionDuration
(TimeUnit unit) Returns the length of time this Task has run.final Task.InputBlocker
Return this task's InputBlocker.Return the value of themessage
property.long
getMessageDuration
(TimeUnit unit) Returns the length of time that has elapsed since themessage
property was last set.final ResourceMap
Returns theResourceMap
used by the constructor to initialize thetitle
,message
, etc properties, and by themessage
method to look up format strings.TaskListener<T,
V>[] Returns a copy of this Task'sTaskListeners
.Returns the TaskService that this Task has been submitted to, or null.getTitle()
Return the value of thetitle
property.boolean
Returns the value of theuserCanCancel
property.protected void
Called if the Task's Thread is interrupted but not explicitly cancelled.final boolean
Equivalent togetState() == StateValue.PENDING
.boolean
Returns true if theprogress
property has been set.final boolean
Equivalent togetState() == StateValue.STARTED
.protected final void
Set the message property to a string generated withString.format
and the specified arguments.protected void
void
removeTaskListener
(TaskListener<T, V> listener) Removes aTaskListener
from this Task.protected final String
resourceName
(String suffix) Returns a Task resource name with the specified suffix.protected void
setDescription
(String description) Set thedescription
property.final void
setInputBlocker
(Task.InputBlocker inputBlocker) Set this task's InputBlocker.protected void
setMessage
(String message) Set themessage
property.protected final void
setProgress
(float percentage) A convenience method that sets theprogress
property topercentage * 100
.protected final void
setProgress
(float value, float min, float max) A convenience method that sets theprogress
property to the following ratio normalized to 0 ..protected final void
setProgress
(int value, int min, int max) A convenience method that sets theprogress
property to the following ratio normalized to 0 ..protected void
Set thetitle
property.protected void
setUserCanCancel
(boolean userCanCancel) Sets theuserCanCancel
property.protected void
Called when this Task has successfully completed, i.e.Methods inherited from class javax.swing.SwingWorker
addPropertyChangeListener, cancel, doInBackground, execute, firePropertyChange, get, get, getProgress, getPropertyChangeSupport, getState, isCancelled, isDone, publish, removePropertyChangeListener, run, setProgress
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
Methods inherited from interface java.util.concurrent.Future
exceptionNow, resultNow, state
-
Constructor Details
-
Task
Deprecated.Warning: This constructor is deprecated. It will be removed in a future release. This constructor was a way for developers to initialize a Task's title/description/message properties, and it's InputBlocker's visual properties, from an alternative ResourceMap. This feature is now supported with the InputBlocker's resourceMap property.Construct a
Task
. If theresourceMap
parameter is not null, then thetitle
,description
, andmessage
properties are initialized from resources. TheresourceMap
is also used to lookup localized messages defined with themessage
method. In both cases, if the value ofresourcePrefix
is not null or an empty string""
, resource names must have the name of theresourcePrefix
parameter, followed by a ".", as a prefix- Parameters:
resourceMap
- the ResourceMap for the Task's user properties, can be nullresourcePrefix
- prefix for resource names, can be null- See Also:
-
Task
Deprecated.Warning: This constructor is deprecated. It will be removed in a future release. This constructor was a way for developers to initialize a Task's title/description/message properties, and it's InputBlocker's visual properties, from an alternative ResourceMap. This feature is now supported with the InputBlocker's resourceMap property.Construct a
Task
with the specified resource name prefix, whose ResourceMap is the value ofApplicationContext.getInstance().getResourceMap(this.getClass(), Task.class)
. TheresourcePrefix
is used to construct the resource names for the intial values of thetitle
,description
, andmessage
Task properties and for messageformat
strings.- Parameters:
resourcePrefix
- prefix for resource names, can be null- See Also:
-
Task
Construct aTask
with an empty (""
) resource name prefix, whose ResourceMap is the value ofApplicationContext.getInstance().getResourceMap(this.getClass(), Task.class)
.
-
-
Method Details
-
getApplication
-
getContext
-
getTaskService
Returns the TaskService that this Task has been submitted to, or null. This property is set when a task is executed by a TaskService, cleared when the task is done and all of its completion methods have run.This is a read-only bound property.
- Returns:
- the value of the taskService property.
- See Also:
-
resourceName
Returns a Task resource name with the specified suffix. Task resource names are the simple name of the constructor'sresourceClass
parameter, followed by ".", followed bysuffix
. If the resourceClass parameter was null, then this method returns an empty string.This method would only be of interest to subclasses that wanted to look up additional Task resources (beyond
title
,message
, etc..) using the same naming convention.- Parameters:
suffix
- the resource name's suffix- See Also:
-
getResourceMap
Returns theResourceMap
used by the constructor to initialize thetitle
,message
, etc properties, and by themessage
method to look up format strings.- Returns:
- this Task's
ResourceMap
- See Also:
-
getTitle
Return the value of thetitle
property. The default value of this property is the value of theresourceMap's
title
resource.Returns a brief one-line description of the this Task that would be useful for describing this task to the user. The default value of this property is null.
- Returns:
- the value of the
title
property. - See Also:
-
setTitle
Set thetitle
property. The default value of this property is the value of theresourceMap's
title
resource.The title is a brief one-line description of the this Task that would be useful for describing it to the user. The
title
should be specific to this Task, for example "Loading image sunset.png" is better than "Image Loader". Similarly the title isn't intended for ephemeral messages, like "Loaded 27.3% of sunset.png". Themessage
property is for reporting the Task's current status.- Parameters:
title
- a brief one-line description of the this Task.- See Also:
-
getDescription
Return the value of thedescription
property. The default value of this property is the value of theresourceMap's
description
resource.A longer version of the Task's title; a few sentences that describe what the Task is for in terms that an application user would understand.
- Returns:
- the value of the
description
property. - See Also:
-
setDescription
Set thedescription
property. The default value of this property is the value of theresourceMap's
description
resource.The description is a longer version of the Task's title. It should be a few sentences that describe what the Task is for, in terms that an application user would understand.
- Parameters:
description
- a few sentences that describe what this Task is for.- See Also:
-
getExecutionDuration
Returns the length of time this Task has run. If the task hasn't started yet (i.e. if its state is stillStateValue.PENDING
), then this method returns 0. Otherwise it returns the duration in the specified time units. For example, to learn how many seconds a Task has run so far:long nSeconds = myTask.getExecutionDuration(TimeUnit.SECONDS);
- Parameters:
unit
- the time unit of the return value- Returns:
- the length of time this Task has run.
- See Also:
-
getMessage
Return the value of themessage
property. The default value of this property is the value of theresourceMap's
message
resource.Returns a short, one-line, message that explains what the task is up to in terms appropriate for an application user.
- Returns:
- a short one-line status message.
- See Also:
-
setMessage
Set themessage
property. The default value of this property is the value of theresourceMap's
message
resource.Returns a short, one-line, message that explains what the task is up to in terms appropriate for an application user. This message should reflect that Task's dynamic state and can be reset as frequently one could reasonably expect a user to understand. It should not repeat the information in the Task's title and should not convey any information that the user shouldn't ignore.
For example, a Task whose
doInBackground
method loaded a photo from a web service might set this property to a new value each time a new internal milestone was reached, e.g.:loadTask.setTitle("Loading photo from http://photos.com/sunset"); // ... loadTask.setMessage("opening connection to photos.com"); // ... loadTask.setMessage("reading thumbnail image file sunset.png"); // ... etc
Each time this property is set, the
messageDuration
property is reset. Since status messages are intended to be ephemeral, application GUI elements like status bars may want to clear messages after 20 or 30 seconds have elapsed.Localized messages that require paramters can be constructed with the
message
method.- Parameters:
message
- a short one-line status message.- See Also:
-
message
Set the message property to a string generated withString.format
and the specified arguments. TheformatResourceKey
names a resource whose value is a format string. See the Task class javadoc for an example.Note that if the no arguments are specified, this method is comparable to:
setMessage(getResourceMap().getString(resourceName(formatResourceKey)));
If a
ResourceMap
was not specified for this Task, then set themessage
property toformatResourceKey
.- Parameters:
formatResourceKey
- the suffix of the format string's resource name.args
- the arguments referred to by the placeholders in the format string- See Also:
-
getMessageDuration
Returns the length of time that has elapsed since themessage
property was last set.- Parameters:
unit
- units for the return value- Returns:
- elapsed time since the
message
property was last set. - See Also:
-
getUserCanCancel
public boolean getUserCanCancel()Returns the value of theuserCanCancel
property. The default value of this property is true.Generic GUI components, like a Task progress dialog, can use this property to decide if they should provide a way for the user to cancel this task.
- Returns:
- true if the user can cancel this Task.
- See Also:
-
setUserCanCancel
protected void setUserCanCancel(boolean userCanCancel) Sets theuserCanCancel
property. The default value of this property is true.Generic GUI components, like a Task progress dialog, can use this property to decide if they should provide a way for the user to cancel this task. For example, the value of this property might be bound to the enabled property of a cancel button.
This property has no effect on the
SwingWorker.cancel(boolean)
cancel method. It's just advice for GUI components that display this Task.- Parameters:
userCanCancel
- true if the user should be allowed to cancel this Task.- See Also:
-
isProgressPropertyValid
public boolean isProgressPropertyValid()Returns true if theprogress
property has been set. Some Tasks don't update the progress property because it's difficult or impossible to determine how what percentage of the task has been completed. GUI elements that display Task progress, like an application status bar, can use this property to set the @{link JProgressBar#indeterminate indeterminate} @{code JProgressBar} property.A task that does keep the progress property up to date should initialize it to 0, to ensure that
isProgressPropertyValid
is always true.- Returns:
- true if the
progress
property has been set. - See Also:
-
setProgress
protected final void setProgress(int value, int min, int max) A convenience method that sets theprogress
property to the following ratio normalized to 0 .. 100.value - min / max - min
- Parameters:
value
- a value in the range min ... max, inclusivemin
- the minimum value of the rangemax
- the maximum value of the range- See Also:
-
setProgress
protected final void setProgress(float percentage) A convenience method that sets theprogress
property topercentage * 100
.- Parameters:
percentage
- a value in the range 0.0 ... 1.0 inclusive- See Also:
-
setProgress
protected final void setProgress(float value, float min, float max) A convenience method that sets theprogress
property to the following ratio normalized to 0 .. 100.value - min / max - min
- Parameters:
value
- a value in the range min ... max, inclusivemin
- the minimum value of the rangemax
- the maximum value of the range- See Also:
-
isPending
public final boolean isPending()Equivalent togetState() == StateValue.PENDING
.When a pending Task's state changes to
StateValue.STARTED
a PropertyChangeEvent for the "started" property is fired. Similarly when a started Task's state changes toStateValue.DONE
, a "done" PropertyChangeEvent is fired. -
isStarted
public final boolean isStarted()Equivalent togetState() == StateValue.STARTED
.When a pending Task's state changes to
StateValue.STARTED
a PropertyChangeEvent for the "started" property is fired. Similarly when a started Task's state changes toStateValue.DONE
, a "done" PropertyChangeEvent is fired. -
process
This method fires the TaskListeners'
process
method. If you overrideprocess
and do not callsuper.process(values)
, then the TaskListeners will not run.- Overrides:
process
in classSwingWorker<T,
V> - Parameters:
values
- @{inheritDoc}
-
done
protected final void done()- Overrides:
done
in classSwingWorker<T,
V>
-
cancelled
protected void cancelled()Called when this Task has been cancelled bySwingWorker.cancel(boolean)
.This method runs on the EDT. It does nothing by default.
- See Also:
-
succeeded
Called when this Task has successfully completed, i.e. when itsget
method returns a value. Tasks that compute a value should override this method.This method runs on the EDT. It does nothing by default.
- Parameters:
result
- the value returned by theget
method- See Also:
-
interrupted
Called if the Task's Thread is interrupted but not explicitly cancelled.This method runs on the EDT. It does nothing by default.
- Parameters:
e
- theInterruptedException
thrown byget
- See Also:
-
failed
Called when an execution of this Task fails and anExecutionExecption
is thrown byget
.This method runs on the EDT. It Logs an error message by default.
- Parameters:
cause
- thecause
of theExecutionException
- See Also:
-
finished
protected void finished()Called unconditionally (in afinally
clause) after one of the completion methods,succeeded
,failed
,cancelled
, orinterrupted
, runs. Subclasses can override this method to cleanup before thedone
method returns.This method runs on the EDT. It does nothing by default.
- See Also:
-
addTaskListener
Adds aTaskListener
to this Task. The listener will be notified when the Task's state changes toSTARTED
, each time theprocess
method is called, and when the Task's state changes toDONE
. All of the listener methods will run on the event dispatching thread.- Parameters:
listener
- theTaskListener
to be added- See Also:
-
removeTaskListener
Removes aTaskListener
from this Task. If the specified listener doesn't exist, this method does nothing.- Parameters:
listener
- theTaskListener
to be added- See Also:
-
getTaskListeners
Returns a copy of this Task'sTaskListeners
.- Returns:
- a copy of this Task's
TaskListeners
. - See Also:
-
getInputBlocker
Return this task's InputBlocker.This is a bound property.
- See Also:
-
setInputBlocker
Set this task's InputBlocker. The InputBlocker defines to what extent the GUI should be blocked while the Task is executed by a TaskService. It is not used by the Task directly, it's used by the TaskService that executes the Task.This property may only be set before the Task is
submitted
to a TaskService for execution. If it's called afterwards, an IllegalStateException is thrown.This is a bound property.
- See Also:
-