简体   繁体   中英

What is the proper way to call complex operation from a wizard in Eclipse RCP?

I am trying to initiate complex operation from a wizard.

It includes showing some view and then initiating of this view, which is long.

First way I was just calling view creation code from wizard's performFinish()

But this was not beautiful, since wizard was hanging on pressing Finish button. User would not see that execution began.

Other way I was trying to call Eclipse command from performFinish() and wrote handler to handle this command. I was thinking this will add some asynchronicity.

Unfortunately, I found no way to pass complex objects to a command. Method org.eclipse.core.commands.Command.executeWithChecks(ExecutionEvent) accepts ExecutionEvent , which allows to pass map of parameters, but values should all be of String type. ExecutionEvent is final and I am unable to add by own properties to it.

So what is the proper way to call complex operation from a wizard in Eclipse RCP?

UPDATE

If I am trying to use Job , I am getting org.eclipse.swt.SWTException: Invalid thread access

UPDATE 2

The same is with IRunnableWithProgress .

Probably I need put view initialization into another thread...

As an alternative to using a Job you can also get the wizard to display a progress bar at the bottom of the wizard while your code is running. To do this call

setNeedsProgressMonitor(true);

in the constructor of your Wizard .

In the performFinish use:

getContainer().run(true, true, new WorkClass());

where WorkClass is a class you define which implements IRunnableWithProgress :

class WorkClass implements IRunnableWithProgress
{
  @Override
  public void run(final IProgressMonitor monitor)
     throws InvocationTargetException, InterruptedException
  {
    // Your work here updating the progress monitor
  }
}

Using this code your wizard will remain open showing a progress bar until the work is done. Using a Job the wizard will close and progress will be show in the status line or a pop-up dialog.

In both cases you need to use Display.asycnExec or Display.syncExec to update the UI:

Display.getDefault().asyncExec(new Runnable()
  {
    @Override
    public void run()
    {
       // Work which updates the UI
    }
  });

If you have a long-running or complex task to execute at the end of the wizard then it's best to just use the wizard to gather and validate information. On performFinish() you can then use the Eclipse Jobs API to asynchronously execute the task.

    Job job = new Job("name") {
        @Override
        protected IStatus run(IProgressMonitor monitor) {
            // TODO Complex task
            return Status.OK_STATUS;
        }
    };
    job.schedule();

If you feed progress information back to the IProgressMonitor then the status of the job will be visible in the Eclipse Progress view.

To pass in information from the wizard you can either extend Job with your own class or just have the job code access fields or final variables in the wizard class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM