The Project        Download   Javadoc   SourceForge

Tasks

TaskManager

Executes tasks synchronously or asynchronously in a dedicated thread. The TaskManager is based on SwingWorker and ExecutorService.

The submit methods schedules the task to be executed and returns immediately. The synchronously tasks are queued and executed in FIFO order.

It's possible to cancel all queue tasks or all tasks from a specific controller group.

Executors

There are 2 types of executor: synchronous and asynchronous.

Available executors:

  • one synchronous executor for all tasks submit through TaskManager
  • one synchronous executor for each controller group
  • one asynchronous executor for all asynchronous task

Tasks

It's the task to be executed. There are 2 types: Task and LinkedTask

Task methods:

  1. doInBackground: computes a result. It's executed in a background thread.
  2. done: It's executed on the Event Dispatch Thread if the doInBackground method finish successfully.
  3. canceled: It's executed on the Event Dispatch Thread if the task is canceled.
  4. removed: It's executed on the Event Dispatch Thread if the task is removed from queue.
  5. handleException: It's executed on the Event Dispatch Thread if the doInBackground method finish with an exception.
  6. setResult and getResult: Used to transfer the computed result from doInBackground method to done method.
  7. retry: Used to submit again the task that throws a exception in doInBackground method.

There are 2 ways to submit tasks:

  1. TaskManager: submit method
  2. All tasks submitted through this method are related to each other.

  3. Controller: execute method
  4. All tasks submitted through this method are connected to the controller. All tasks submitted by the same group of controllers are related to each other.

A task can cancel or remove your related tasks in queue.

Types
  1. Task: simple task that defines a generic type for the computed result.
  2. LinkedTask: task that receives the computed result from another task in his doInBackground method.
Task Example

 Task<String> task = new Task<String>() { 
   @Override 
   protected void doInBackground() throws Exception { 
     setResult("testing..."); 
   } 
 
   @Override 
   protected void done() { 
     System.out.println(getResult()); 
   } 
 }; 
 TaskManager.submit(task); 

LinkedTask Example

 Task<String> task = new Task<String>() { 
   @Override 
   protected void doInBackground() throws Exception { 
     setResult("testing..."); 
   } 
 
   @Override 
   protected void done() { 
     System.out.println(getResult()); 
   } 
 }; 
 
 LinkedTask<Boolean, String> linkedTask = new LinkedTask<Boolean, String>() { 
   @Override 
   protected void doInBackground(String linkedResult) throws Exception { 
     if (linkedResult.startsWith("testing")) { 
       setResult(true); 
     } else { 
       setResult(false); 
     } 
   } 
 
   @Override 
   protected void done() { 
     System.out.println(getResult()); 
   } 
 }; 
 
 linkedTask.receiveResultFrom(task); 
 TaskManager.submit(task); 
 TaskManager.submit(linkedTask); 

Wrapping Runnable or Callable

 Runnable runnable = new Runnable() { 
   @Override 
   public void run() { 
     ... 
   } 
 }; 
 
 Callable<String> callable = new Callable<String>() { 
   @Override 
   public String call() throws Exception { 
     ... 
     return "test"; 
   } 
 }; 
 
 CallableWrapper<String> callableWrapper = 
     new CallableWrapper<String>(callable) { 
       @Override 
       protected void done() { 
         System.out.println(getResult()); 
       } 
     }; 
 
 TaskManager.submit(new RunnableWrapper(runnable)); 
 TaskManager.submit(callableWrapper); 

Nested tasks

A task set as nested will be executed immediately if it is submitted in the execution of the willExecute or doInBackground method from another task on the same TaskManager thread.

Example:

 final Task<String> nestedTask1 = new Task<String>() { 
   @Override 
   protected void doInBackground() throws Exception { 
     setResult("nested task 1"); 
   } 
 
   @Override 
   protected void done() { 
     System.out.println(getResult()); 
   } 
 }; 
 nestedTask1.setMode(Mode.NESTED); 
 
 final Task<String> nestedTask2 = new Task<String>() { 
   @Override 
   protected void doInBackground() throws Exception { 
     setResult("nested task 2"); 
   } 
 
   @Override 
   protected void done() { 
     System.out.println(getResult()); 
   } 
 }; 
 nestedTask2.setMode(Mode.NESTED); 
 
 Task<String> task1 = new Task<String>() { 
   @Override 
   protected void doInBackground() throws Exception { 
     Thread t = new Thread(new Runnable() { 
       @Override 
       public void run() { 
         // other thread: task will queue 
         TaskManager.submit(nestedTask1); 
       } 
     }); 
     t.start(); 
 
     // executes immediately 
     TaskManager.submit(nestedTask2); 
     setResult("task 1"); 
   } 
 
   @Override 
   protected void done() { 
     System.out.println(getResult()); 
   } 
 }; 
 
 Task<String> task2 = new Task<String>() { 
   @Override 
   protected void doInBackground() throws Exception { 
     setResult("task 2"); 
   } 
 
   @Override 
   protected void done() { 
     System.out.println(getResult()); 
   } 
 }; 
 
 TaskManager.showDebugWindow(); 
 
 nestedTask1.setName("nestedTask1"); 
 nestedTask2.setName("nestedTask2"); 
 task1.setName("task1"); 
 task2.setName("task2"); 
 
 TaskManager.submit(task1); 
 TaskManager.submit(task2); 

Result:

nested task 2
task 1
task 2
nested task 1

Task livecycle

Exceptions

When an exception is thrown in the doInBackground method, the exception is set in the task and redirected to the handleException method in the Event Dispatch Thread. All related tasks are removed.

The default implementation of the handleException method is pass the exception to:

  1. HandlerExceptionManager
  2. taskExecutionError method from the controller that submitted the task and the root controller
Retry

The retry method submits and runs the task immediately. It can only be used in the handleException task method or afterException listener method. The task is submitted together with other related tasks that were removed.

Example:

 Task<String> task1 = new Task<String>() { 
 
   private boolean throwException = true; 
 
   @Override 
   protected void doInBackground() throws Exception { 
     System.out.println("doInBackground: task1"); 
     if (throwException) { 
       throwException = false; 
       throw new Exception(); 
     } 
     setResult("task1"); 
   } 
 
   @Override 
   protected void handleException(Exception e) { 
     retry(); 
   } 
 
   @Override 
   protected void done() { 
     System.out.println("done: " + getResult()); 
   } 
 }; 
 
 Task<String> task2 = new Task<String>() { 
   @Override 
   protected void doInBackground() throws Exception { 
     System.out.println("doInBackground: task2"); 
     setResult("task2"); 
   } 
 
   @Override 
   protected void removed() { 
     System.out.println("removed: task2"); 
   } 
 
   @Override 
   protected void done() { 
     System.out.println("done: " + getResult()); 
   } 
 }; 
 
 task1.setName("task1"); 
 task2.setName("task2"); 
 
 TaskManager.submit(task1); 
 TaskManager.submit(task2); 

Result:

doInBackground: task1
removed: task2
doInBackground: task1
done: task1
doInBackground: task2
done: task2

TaskManager Background Thread / Event Dispatch Thread

The doInBackground Task method is executed in the TaskManager background thread.

The isWaitForEDT and setWaitForEDT Task methods defines if the TaskManager need wait for EDT to execute the next task.

The waitForEDT parameter is set to false by default.

Attention: A modal dialog displayed in a task set to wait for the EDT will block the TaskManager Background Thread until it is disposed.


Visual Effects

Tasks do not have visual effects. It's possible to apply any visual effect with the listeners.

Exemple:

The default visual effect for Controller is the TaskExecutionProgressListener.

Exemple:

DebugWindow

Displays the status of the tasks.

Use the static TaskManager method showDebugWindow to show the DebugWindow.

 

Partners