Running Task asynchronously in Eclipse RCP and JFace

These code snippets show how it is possible to executes task in Eclipse by showing a progress dialog, which is possible to hide

This is the code to start the job:

// create action to be called after the action is completed
// this action shows a success dialog if the job executed without
// an exception, otherwise it shows an error dialog
final CompletionAction completionAction = new 
        CompletionAction(AdminClientActivator.PLUGIN_ID, parent.getShell(), view);
completionAction.setOkTitle("Job sucess");
completionAction.setOkMsg("Sucessfully executed job");
completionAction.setFailTitle("Job failed");
completionAction.setFailMsg("There was an exception while executing job");

RSPClientJob job = new ClientJob("Long job...", completionAction);

// if short action, otherwise is long Job.LONG
// show a dialog immediately
// start as soon as possible

This snippet is the Job class:

 * Abstract {@link Job} class for executing tasks with a progress dialog
 * @author Robert von Burg
public class ClientJob extends Job {
  private CompletionAction completedAction;

   * @param name
   * @param completedAction
  public ClientJob(String name, CompletionAction completedAction) {
    this.completedAction = completedAction;

  protected IStatus run(IProgressMonitor monitor) {
    // activate the progress bar with an unknown amount of task work
    monitor.beginTask("Loading Hibernate configuration", IProgressMonitor.UNKNOWN);
    // perform the job
    try {
      // execute task work...
      // at the end of the successfully ended work, set the completion
      // task to be ok
    } catch (Exception e1) {
      logger.error(e1, e1);
      // if the work failed then set the completion
      // task to be NOT ok and set the exception so it
      // can be shown to the user
    // stop the monitor
    // execute the completion task
    return Status.OK_STATUS;

   * completes the task by showing the user a dialog about the execution 
   * state of the job
  protected void complete() {
    setProperty(IProgressConstants.ICON_PROPERTY, ImageFactory.
    Boolean isModal = (Boolean) this.getProperty(
    if (isModal != null && isModal.booleanValue()) {
      // The progress dialog is still open so
      // just open the message
    } else {
      setProperty(IProgressConstants.KEEP_PROPERTY, Boolean.TRUE);
      setProperty(IProgressConstants.ACTION_PROPERTY, completedAction);

   * Asynchronous execution of an {@link Action}
   * @param action
  protected static void showResults(final Action action) {
    Display.getDefault().asyncExec(new Runnable() {
      public void run() {;

And since we want to notify the caller about task completion we use this interface:

 * Interface for notifying objects to be refreshed
 * @author robertb
public interface Refreshable {
  public void refresh();

And task completion is handled with this Action:

 * The completion task, which either shows a success dialog, or an error dialog, 
 * depending on the ok state set and then notifies the {@link Refreshable} to 
 * refresh its contents
 * @author robertb
public class CompletionAction extends Action {
  private boolean ok;
  private String okTitle;
  private String okMsg;
  private String failMsg;
  private String failTitle;
  private Throwable throwable;

  private Refreshable refreshable;
  private Shell shell;
  private String pluginId;

   * @param pluginId
   * @param shell
   * @param refreshable
  public CompletionAction(String pluginId, Shell shell, Refreshable refreshable) {
    this.pluginId = pluginId; = shell;
    this.refreshable = refreshable;

  public void setOk(boolean ok) {
    this.ok = ok;

  public void setOkTitle(String okTitle) {
    this.okTitle = okTitle;

  public void setOkMsg(String okMsg) {
    this.okMsg = okMsg;

  public void setFailMsg(String failMsg) {
    this.failMsg = failMsg;

  public void setFailTitle(String failTitle) {
    this.failTitle = failTitle;

  public void setThrowable(Throwable throwable) {
    this.throwable = throwable;

  public void run() {
    // first refresh
    // then show the dialog
    if (ok) {
      MessageDialog.openInformation(shell, okTitle, okMsg);
    } else {
      Status status = new Status(IStatus.ERROR, pluginId, 
                throwable.getLocalizedMessage(), throwable);
      ErrorDialog.openError(shell, failTitle, failMsg, status);

I put this together with help from the following site:
Job Concurrency


One Comment

Comments are closed.