Class Task<T,V>
- java.lang.Object
-
- javax.swing.SwingWorker<T,V>
-
- org.jdesktop.application.Task<T,V>
-
- All Implemented Interfaces:
java.lang.Runnable
,java.util.concurrent.Future<T>
,java.util.concurrent.RunnableFuture<T>
- Direct Known Subclasses:
LoadImageTask
public abstract class Task<T,V> extends javax.swing.SwingWorker<T,V>
A type ofSwingWorker
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 aTaskListener
that enables one to monitor the three key SwingWorker methods:doInBackground
,process
anddone
.When a Task completes, the
final done
method invokes one ofsucceeded
,cancelled
,interrupted
, orfailed
. Thefinal done
method invokesfinished
when the completion method returns or throws an exception.Tasks should provide localized values for the
title
,description
, andmessage
properties in a ResourceBundle for the Task subclass. AResourceMap
is loaded automatically using the Task subclass as thestartClass
and Task.class thestopClass
. This ResourceMap is also used to look up format strings used in calls tomessage
, which is used to set themessage
property.For example: given a Task called
MyTask
defined like this:class MyTask extends Task
Typically the resources for this class would be defined in the MyTask ResourceBundle, @{code resources/MyTask.properties}:{ protected MyResultType doInBackground() { message("startMessage", getPlannedSubtaskCount()); // do the work ... if an error is encountered: message("errorMessage"); message("finishedMessage", getActualSubtaskCount(), getFailureCount()); // .. return the result } } 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. TheinputBlocker
is set automatically when an@Action
method that returns a Task specifies aTask.BlockingScope
value for theblock
annotation parameter. To customize the way blocking is implemented you can define your ownTask.InputBlocker
. For example, assume thatbusyGlassPane
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, allPropertyChangeListeners
run on the event dispatching thread. This is also true ofTaskListeners
.Unless specified otherwise specified, this class is thread-safe. All of the Task properties can be get/set on any thread.
- See Also:
ApplicationContext
,ResourceMap
,TaskListener
,TaskEvent
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
Task.BlockingScope
Specifies to what extent the GUI should be blocked a Task is executed by a TaskService.static class
Task.InputBlocker
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.
-
Constructor Summary
Constructors Constructor Description Task(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, java.lang.String resourcePrefix)
Deprecated.Task(Application application, ResourceMap resourceMap, java.lang.String resourcePrefix)
Deprecated.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
addTaskListener(TaskListener<T,V> listener)
Adds aTaskListener
to this Task.protected void
cancelled()
Called when this Task has been cancelled bySwingWorker.cancel(boolean)
.protected void
done()
protected void
failed(java.lang.Throwable cause)
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.Application
getApplication()
ApplicationContext
getContext()
java.lang.String
getDescription()
Return the value of thedescription
property.long
getExecutionDuration(java.util.concurrent.TimeUnit unit)
Returns the length of time this Task has run.Task.InputBlocker
getInputBlocker()
Return this task's InputBlocker.java.lang.String
getMessage()
Return the value of themessage
property.long
getMessageDuration(java.util.concurrent.TimeUnit unit)
Returns the length of time that has elapsed since themessage
property was last set.ResourceMap
getResourceMap()
Returns theResourceMap
used by the constructor to initialize thetitle
,message
, etc properties, and by themessage
method to look up format strings.TaskListener<T,V>[]
getTaskListeners()
Returns a copy of this Task'sTaskListeners
.TaskService
getTaskService()
Returns the TaskService that this Task has been submitted to, or null.java.lang.String
getTitle()
Return the value of thetitle
property.boolean
getUserCanCancel()
Returns the value of theuserCanCancel
property.protected void
interrupted(java.lang.InterruptedException e)
Called if the Task's Thread is interrupted but not explicitly cancelled.boolean
isPending()
Equivalent togetState() == StateValue.PENDING
.boolean
isProgressPropertyValid()
Returns true if theprogress
property has been set.boolean
isStarted()
Equivalent togetState() == StateValue.STARTED
.protected void
message(java.lang.String formatResourceKey, java.lang.Object... args)
Set the message property to a string generated withString.format
and the specified arguments.protected void
process(java.util.List<V> values)
void
removeTaskListener(TaskListener<T,V> listener)
Removes aTaskListener
from this Task.protected java.lang.String
resourceName(java.lang.String suffix)
Returns a Task resource name with the specified suffix.protected void
setDescription(java.lang.String description)
Set thedescription
property.void
setInputBlocker(Task.InputBlocker inputBlocker)
Set this task's InputBlocker.protected void
setMessage(java.lang.String message)
Set themessage
property.protected void
setProgress(float percentage)
A convenience method that sets theprogress
property topercentage * 100
.protected void
setProgress(float value, float min, float max)
A convenience method that sets theprogress
property to the following ratio normalized to 0 ..protected void
setProgress(int value, int min, int max)
A convenience method that sets theprogress
property to the following ratio normalized to 0 ..protected void
setTitle(java.lang.String title)
Set thetitle
property.protected void
setUserCanCancel(boolean userCanCancel)
Sets theuserCanCancel
property.protected void
succeeded(T result)
Called when this Task has successfully completed, i.e.
-
-
-
Constructor Detail
-
Task
@Deprecated public Task(Application application, ResourceMap resourceMap, java.lang.String resourcePrefix)
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:
getResourceMap()
,setTitle(java.lang.String)
,setDescription(java.lang.String)
,setMessage(java.lang.String)
,resourceName(java.lang.String)
,ApplicationContext.getResourceMap(java.lang.Class)
-
Task
@Deprecated public Task(Application application, java.lang.String resourcePrefix)
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:
getResourceMap()
,setTitle(java.lang.String)
,setDescription(java.lang.String)
,setMessage(java.lang.String)
,resourceName(java.lang.String)
,ApplicationContext.getResourceMap(java.lang.Class)
-
Task
public Task(Application application)
Construct aTask
with an empty (""
) resource name prefix, whose ResourceMap is the value ofApplicationContext.getInstance().getResourceMap(this.getClass(), Task.class)
.
-
-
Method Detail
-
getApplication
public final Application getApplication()
-
getContext
public final ApplicationContext getContext()
-
getTaskService
public TaskService 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:
TaskService.execute(org.jdesktop.application.Task)
,done()
-
resourceName
protected final java.lang.String resourceName(java.lang.String suffix)
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()
,message
-
getResourceMap
public final ResourceMap 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:
resourceName(java.lang.String)
-
getTitle
public java.lang.String 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(java.lang.String)
,setDescription(java.lang.String)
,setMessage(java.lang.String)
-
setTitle
protected void setTitle(java.lang.String title)
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:
getTitle()
,setDescription(java.lang.String)
,setMessage(java.lang.String)
-
getDescription
public java.lang.String 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(java.lang.String)
,setTitle(java.lang.String)
,setMessage(java.lang.String)
-
setDescription
protected void setDescription(java.lang.String description)
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:
getDescription()
,setTitle(java.lang.String)
,setMessage(java.lang.String)
-
getExecutionDuration
public long getExecutionDuration(java.util.concurrent.TimeUnit unit)
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:
SwingWorker.execute()
-
getMessage
public java.lang.String 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(java.lang.String)
,getMessageDuration(java.util.concurrent.TimeUnit)
-
setMessage
protected void setMessage(java.lang.String message)
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:
getMessage()
,getMessageDuration(java.util.concurrent.TimeUnit)
,message
-
message
protected final void message(java.lang.String formatResourceKey, java.lang.Object... args)
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:
setMessage(java.lang.String)
,ResourceMap.getString(String, Object...)
,MessageFormat
-
getMessageDuration
public long getMessageDuration(java.util.concurrent.TimeUnit unit)
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:
setMessage(java.lang.String)
-
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(boolean)
-
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:
getUserCanCancel()
-
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(int, int, int)
-
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:
SwingWorker.setProgress(int)
-
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:
SwingWorker.setProgress(int)
-
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:
SwingWorker.setProgress(int)
-
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
protected void process(java.util.List<V> values)
This method fires the TaskListeners'
process
method. If you overrideprocess
and do not callsuper.process(values)
, then the TaskListeners will not run.
-
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:
done()
-
succeeded
protected void succeeded(T result)
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:
done()
,SwingWorker.get()
,failed(java.lang.Throwable)
-
interrupted
protected void interrupted(java.lang.InterruptedException e)
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:
SwingWorker.cancel(boolean)
,done()
,SwingWorker.get()
-
failed
protected void failed(java.lang.Throwable cause)
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:
done()
,SwingWorker.get()
,failed(java.lang.Throwable)
-
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:
done()
,SwingWorker.get()
,failed(java.lang.Throwable)
-
addTaskListener
public void addTaskListener(TaskListener<T,V> listener)
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(org.jdesktop.application.TaskListener<T, V>)
-
removeTaskListener
public void removeTaskListener(TaskListener<T,V> listener)
Removes aTaskListener
from this Task. If the specified listener doesn't exist, this method does nothing.- Parameters:
listener
- theTaskListener
to be added- See Also:
addTaskListener(org.jdesktop.application.TaskListener<T, V>)
-
getTaskListeners
public TaskListener<T,V>[] getTaskListeners()
Returns a copy of this Task'sTaskListeners
.- Returns:
- a copy of this Task's
TaskListeners
. - See Also:
addTaskListener(org.jdesktop.application.TaskListener<T, V>)
,removeTaskListener(org.jdesktop.application.TaskListener<T, V>)
-
getInputBlocker
public final Task.InputBlocker getInputBlocker()
Return this task's InputBlocker.This is a bound property.
-
setInputBlocker
public final void setInputBlocker(Task.InputBlocker inputBlocker)
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:
getInputBlocker()
-
-