Previous Page
Next Page

9.4. Progress Monitor

For long-running operations, the progress monitor indicates what the operation is doing and an estimate of how much more there is left to be done. In the preceding code, a progress monitor was used to communicate with the user, indicating that resources were being deleted and how many resources needed to be deleted before the operation completed (see methods in previous sections and the redo() method in Section 8.5.3, Undo/Redo, on page 362).

In addition, since DeleteResourcesOperation interacts with the user interface, isCanceled() is called periodically to see if the user has canceled the operation. There is nothing more frustrating than looking at a long running operation with a cancel button only to find out that the cancel button has no effect.

9.4.1. IProgressMonitor

The org.eclipse.core.runtime.IProgressMonitor interface provides methods for indicating when an operation has started, how much has been done, and when it is complete.

beginTask(String, int) Called once by the operation to indicate that the operation has started and approximately how much work must be done before it is complete. This method must be called exactly once per instance of a progress monitor.

done() Called by the operation to indicate that it is complete.

isCanceled() The operation should periodically poll this method to see whether the user has requested that the operation be canceled.

setCanceled(boolean) This method is typically called by UI code setting the canceled state to true when the user clicks on the Cancel button during an operation.

setTaskName(String) Sets the task name displayed to the user. Usually, there is no need to call this method because the task name is set by beginTask(String, int).

worked(int) Called by the operation to indicate that the specified number of units of work has been completed.

The IProgressMonitorWithBlocking interface extends IProgressMonitor for monitors that want to support feedback when an activity is blocked due to concurrent activity in another thread. If a running operation ever calls the setBlocked method listed below, it must eventually call clearBlocked before the operation completes.

clearBlocked() Called by an operation to indicate that the operation is no longer blocked.

setBlocked(IStatus) Called by an operation to indicate that this operation is blocked by some background activity.

9.4.2. Classes for displaying progress

Eclipse provides several classes that either implement the IProgressMonitor interface or provide a progress monitor via the IRunnableWithProgress interface. These classes are used under different circumstances to notify the user of the progress of long-running operations.

SubProgressMonitor A progress monitor passed by a parent operation to a suboperation so that the suboperation can notify the user of progress as a portion of the parent operation (see Section 9.3, Batching Change Events, on page 382).

NullProgressMonitor A progress monitor that supports cancellation but does not provide any user feedback. Suitable for subclassing.

ProgressMonitorWrapper A progress monitor that wrappers another progress monitor and forwards IProgressMonitor and IProgressMonitorWithBlocking methods to the wrapped progress monitor. Suitable for subclassing.

WorkspaceModifyOperation An operation that batches resource change events and provides a progress monitor as part of its execution (see Section 9.3, Batching Change Events, on page 382).

ProgressMonitorPart An SWT composite consisting of a label displaying the task and subtask name, and a progress indicator to show progress.

ProgressMonitorDialog Opens a dialog that displays progress to the user and provides a progress monitor used by the operation to relate that information.

TimeTriggeredProgressMonitorDialog Waits for a specified amount of time during operation execution then opens a dialog that displays progress to the user and provides a progress monitor used by the operation to relate that information. If the operation completes before the specified amount of time, then no dialog is opened. This is an internal workbench class but listed here because the concept and its functionality is interesting. For more, see Section 9.4.4, IProgressService, on page 386 and Bugzilla entry 123797 at bugs.eclipse.org/bugs/show_bug.cgi?id=123797.

WizardDialog When opened, optionally provides progress information as part of the wizard. The wizard implements the IRunnableContext, and thus the operation can call run(boolean, boolean, IRunnableWithProgress) and display progress in the wizard via the provided progress monitor (see Section 11.2.3, IWizardContainer, on page 434 and Section 11.2.6, Wizard example, on page 439).

9.4.3. Workbench window status bar

The workbench window provides a progress display area along the bottom edge of the window. Use the IWorkbenchWindow.run() method to execute the operation and the progress monitor passed to IRunnableWithProgress will be the progress monitor in the status bar. For example, the following snippet from an action delegate (see Section 6.2.6, Creating an action delegate, on page 216 for more on creating action delegates) shows simulated progress in the status bar:

private IWorkbenchWindow window;
public void init(IWorkbenchWindow window) {
   this.window = window;
}
public void run(IAction action) {
   try {
      window.run(true, true, new IRunnableWithProgress() {
         public void run(IProgressMonitor monitor)
            throws InvocationTargetException, InterruptedException {
            monitor.beginTask("simulate status bar progress:", 20);
            for (int i = 20; i > 0; --i) {
               monitor.subTask("seconds left = " + i);
               Thread.sleep(1000);
               monitor.worked(1);
            }
            monitor.done();
         }
      });
   }
   catch (InvocationTargetException e) {
      FavoritesLog.logError(e);
   }
   catch (InterruptedException e) {
      // User canceled the operation... just ignore.
   }
}

If you have a view or editor, you can obtain the containing IWorkbenchWindow via IWorkbenchPart, which both IViewPart and IEditorPart extend.

IWorkbenchWindow window
   = viewOrEditor.getWorkbenchSite().getWorkbenchWindow();

You can also obtain the progress monitor in the status bar directly via the IStatusLineManager interface.

viewPart.getViewSite().getActionBars()
   .getStatusLineManager().getProgressMonitor()

or:

editorPart.getEditorSite().getActionBars()
   .getStatusLineManager().getProgressMonitor()

9.4.4. IProgressService

Yet another mechanism for displaying progress in the workbench is using the IProgressService interface. While the run() method in IWorkbenchWindow displays progress in the status bar, the IProgressService interface displays progress using a subclass of ProgressMonitorDialog named TimeTriggeredProgressMonitorDialog. Although you could use a ProgressMonitorDialog, IProgressService only opens a progress dialog if the operation takes longer to execute than a specified amount of time (currently 800 milliseconds).

window.getWorkbench().getProgressService().run(true, true,
   new IRunnableWithProgress() {
      public void run(IProgressMonitor monitor)
         throws InvocationTargetException, InterruptedException
       {
         monitor.beginTask("Simulated long running task #1", 60);
         for (int i = 60; i > 0; --i) {
            monitor.subTask("seconds left = " + i);
            if (monitor.isCanceled()) break;
            Thread.sleep(1000);
            monitor.worked(1);
         }
         monitor.done();
       }
   });

Typically, jobs are executed in the background (see Section 20.8, Background TasksJobs API, on page 739), but the IProgressService provides the showInDialog() method for executing them in the foreground.


Previous Page
Next Page