Class Task<T,V>

java.lang.Object
javax.swing.SwingWorker<T,V>
org.jdesktop.application.Task<T,V>
All Implemented Interfaces:
Runnable, Future<T>, RunnableFuture<T>
Direct Known Subclasses:
LoadImageTask

public abstract class Task<T,V> extends SwingWorker<T,V>
A type of 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:
  • Constructor Details

    • Task

      @Deprecated public Task(Application application, ResourceMap resourceMap, 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 the resourceMap parameter is not null, then the title, description, and message properties are initialized from resources. The resourceMap is also used to lookup localized messages defined with the message method. In both cases, if the value of resourcePrefix is not null or an empty string "", resource names must have the name of the resourcePrefix parameter, followed by a ".", as a prefix

      Parameters:
      resourceMap - the ResourceMap for the Task's user properties, can be null
      resourcePrefix - prefix for resource names, can be null
      See Also:
    • Task

      @Deprecated public Task(Application application, 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 of ApplicationContext.getInstance().getResourceMap(this.getClass(), Task.class) . The resourcePrefix is used to construct the resource names for the intial values of the title, description, and message Task properties and for message format strings.

      Parameters:
      resourcePrefix - prefix for resource names, can be null
      See Also:
    • Task

      public Task(Application application)
      Construct a Task with an empty ("") resource name prefix, whose ResourceMap is the value of ApplicationContext.getInstance().getResourceMap(this.getClass(), Task.class).
  • Method Details

    • 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:
    • resourceName

      protected final String resourceName(String suffix)
      Returns a Task resource name with the specified suffix. Task resource names are the simple name of the constructor's resourceClass parameter, followed by ".", followed by suffix. 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

      public final ResourceMap getResourceMap()
      Returns the ResourceMap used by the constructor to initialize the title, message, etc properties, and by the message method to look up format strings.
      Returns:
      this Task's ResourceMap
      See Also:
    • getTitle

      public String getTitle()
      Return the value of the title property. The default value of this property is the value of the resourceMap'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

      protected void setTitle(String title)
      Set the title property. The default value of this property is the value of the resourceMap'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". The message property is for reporting the Task's current status.

      Parameters:
      title - a brief one-line description of the this Task.
      See Also:
    • getDescription

      public String getDescription()
      Return the value of the description property. The default value of this property is the value of the resourceMap'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

      protected void setDescription(String description)
      Set the description property. The default value of this property is the value of the resourceMap'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

      public long getExecutionDuration(TimeUnit unit)
      Returns the length of time this Task has run. If the task hasn't started yet (i.e. if its state is still StateValue.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

      public String getMessage()
      Return the value of the message property. The default value of this property is the value of the resourceMap'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

      protected void setMessage(String message)
      Set the message property. The default value of this property is the value of the resourceMap'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

      protected final void message(String formatResourceKey, Object... args)
      Set the message property to a string generated with String.format and the specified arguments. The formatResourceKey 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 the message property to formatResourceKey.

      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

      public long getMessageDuration(TimeUnit unit)
      Returns the length of time that has elapsed since the message 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 the userCanCancel 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 the userCanCancel 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 the progress 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 the progress property to the following ratio normalized to 0 .. 100.
       value - min / max - min
       
      Parameters:
      value - a value in the range min ... max, inclusive
      min - the minimum value of the range
      max - the maximum value of the range
      See Also:
    • setProgress

      protected final void setProgress(float percentage)
      A convenience method that sets the progress property to percentage * 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 the progress property to the following ratio normalized to 0 .. 100.
       value - min / max - min
       
      Parameters:
      value - a value in the range min ... max, inclusive
      min - the minimum value of the range
      max - the maximum value of the range
      See Also:
    • isPending

      public final boolean isPending()
      Equivalent to getState() == 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 to StateValue.DONE, a "done" PropertyChangeEvent is fired.

    • isStarted

      public final boolean isStarted()
      Equivalent to getState() == 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 to StateValue.DONE, a "done" PropertyChangeEvent is fired.

    • process

      protected void process(List<V> values)

      This method fires the TaskListeners' process method. If you override process and do not call super.process(values), then the TaskListeners will not run.

      Overrides:
      process in class SwingWorker<T,V>
      Parameters:
      values - @{inheritDoc}
    • done

      protected final void done()
      Overrides:
      done in class SwingWorker<T,V>
    • cancelled

      protected void cancelled()
      Called when this Task has been cancelled by SwingWorker.cancel(boolean).

      This method runs on the EDT. It does nothing by default.

      See Also:
    • succeeded

      protected void succeeded(T result)
      Called when this Task has successfully completed, i.e. when its get 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 the get method
      See Also:
    • interrupted

      protected void interrupted(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 - the InterruptedException thrown by get
      See Also:
    • failed

      protected void failed(Throwable cause)
      Called when an execution of this Task fails and an ExecutionExecption is thrown by get.

      This method runs on the EDT. It Logs an error message by default.

      Parameters:
      cause - the cause of the ExecutionException
      See Also:
    • finished

      protected void finished()
      Called unconditionally (in a finally clause) after one of the completion methods, succeeded, failed, cancelled, or interrupted, runs. Subclasses can override this method to cleanup before the done method returns.

      This method runs on the EDT. It does nothing by default.

      See Also:
    • addTaskListener

      public void addTaskListener(TaskListener<T,V> listener)
      Adds a TaskListener to this Task. The listener will be notified when the Task's state changes to STARTED, each time the process method is called, and when the Task's state changes to DONE. All of the listener methods will run on the event dispatching thread.
      Parameters:
      listener - the TaskListener to be added
      See Also:
    • removeTaskListener

      public void removeTaskListener(TaskListener<T,V> listener)
      Removes a TaskListener from this Task. If the specified listener doesn't exist, this method does nothing.
      Parameters:
      listener - the TaskListener to be added
      See Also:
    • getTaskListeners

      public TaskListener<T,V>[] getTaskListeners()
      Returns a copy of this Task's TaskListeners.
      Returns:
      a copy of this Task's TaskListeners.
      See Also:
    • getInputBlocker

      public final Task.InputBlocker getInputBlocker()
      Return this task's InputBlocker.

      This is a bound property.

      See Also:
    • 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: