Working with Long Tasks

Simple tasks can be run on the AWT event thread. For more complex tasks, you can use the API com.interactive.intviewerapi.longtask.ILongTask classes to run tasks on a background thread. This will prevent the application from stalling for an extended length of time.

Please note, all Swing components and related classes, unless otherwise documented, must be accessed on the event dispatching thread. You cannot use long tasks to change Swing components, such as windows.

A walkthrough is available for examples of uses of long tasks.

ILongTask

This interface should be implemented by any task that needs to be executed in a background thread.

ILONGTASK EXAMPLE

public class ExampleTask implements ILongTask<Void> {
   ...
   public Void run(ILongTaskProgressMonitor monitor) throws LongTaskException {
        // run the long task
        return null;
    }
}

This example shows a task which returns nothing. Use the LongTaskRunner to run this task.

LongTaskRunner.run("Run a long task", new ExampleTask(), true);

The first argument string is a display title for the progress bar, the second argument is your long task, the third argument, if true, will display a dialog with a cancel option.

Long Task Monitor

The progress display has two modes, as shown in the image below. If progress is not being tracked, the display will act as a "busy" indicator, as shown in the image on the left. If a progress status is desired, just set the monitor.setTaskLengthKnown() method and call the monitor.progress() method at intervals to update the progress, as shown in the image on the right. The small x button at the right of the status bar gives the user the option of cancelling the long task.

Working Status Percent Done Status

Creating a ILongTask returning data

ILONGTASK WITH DATA RETURNED

public class TaskExample2 implements ILongTask<IHorizonData> {
    private IHorizonData _exampleData = null;
    public TaskExample2(IHorizonData data) {
        _exampleData = data;
    }
   
    public IHorizonData run(ILongTaskProgressMonitor m) throws LongTaskException {
        if (_horizonData == null) {
            throw new LongTaskException(new Exception("No horizon data specified."));
        }
        return interpolateHorizon();
    }  
    private IHorizonData interpolateHorizon() {
    ....
    }
}

This example shows a task which returns data.

Handling Cancellations

ILongTask implementations will receive an interrupt when the users clicks the cancel button.

Some methods will respond if you interrupt them. For example, Thread.sleep responds with an interrupted exception if interrupted. If this is the case, the ILongTask implementation should catch the exception and end the task.

ILONGTASK CANCEL WITH BLOCKING METHOD

try {
  Thread.sleep(1000);
} catch (InterruptedException e) {
    /* Allow thread to exit */
}
For tasks that execute code in a loop, it is common to check the interrupted status once per loop iteration.

ILONGTASK WITH CANCEL

while (notDoneYet) {
  doSomething();
  if (this.isCancelled())
    return;
}

Using LongTaskRunner

USING ILONGTASK RETURN DATA

            LongTaskRunner.run("Interpolating Horizon", new TaskExample2(refHorizonData), new ITaskFinishedAction<IHorizonData>() {
                @Override
                public void run(IHorizonData data) {
                    if (data != null) {
                        updateAll(data);
                    }
                }
            }, true);

This example shows how to implement the LongTaskRunner when a return action is required.

The first argument string is a display title for the progress bar, the second argument is your long task, the third argument, passes the return data from your long task to the specified action, the fourth argument, if true, will display a dialog with a cancel option.

Running a long task in a blocking dialog

By default, running long tasks is non-blocking. the LongTaskRunner also has a method to run a long task inside a modal dialog.

USING RUNANDWAIT

            ILongTask task = new ....
            if ((numberOfBytes > 1000000) && (SwingUtilities.isEventDispatchThread())) {
                return LongTaskRunner.runAndWait("Reading File", task, true);
            } else {
                return LongTaskRunner.runAndWait("Reading File", task, false);
            }