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:
doInBackground: computes a result. It's executed in a background thread.
done: It's executed on the Event Dispatch Thread if the doInBackground method finish successfully.
canceled: It's executed on the Event Dispatch Thread if the task is canceled.
removed: It's executed on the Event Dispatch Thread if the task is removed from queue.
handleException: It's executed on the Event Dispatch Thread if the doInBackground method finish with an exception.
setResult and getResult: Used to transfer the computed result from doInBackground method to done method.
retry: Used to submit again the task that throws a exception in doInBackground method.
There are 2 ways to submit tasks:
- TaskManager:
submit method
All tasks submitted through this method are related to each other.
- Controller:
execute method
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
- Task: simple task that defines a generic type for the computed result.
- 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:
- HandlerExceptionManager
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.

|