Search code examples
eclipse-plugineclipse-rcpeclipse-cdtjobs

Give the message to the user while running the job


I have a method buildTargets() which is called when the user clicks on one of the UI menu operations.

static public void buildTargets(Shell shell, final IMakeTarget[] targets) {
        saveAllResources(targets);
        Job targetJob = new Job(MakeUIPlugin.getResourceString("TargetBuild.backgroundTask.name")) { //$NON-NLS-1$
            @Override
            protected IStatus run(IProgressMonitor monitor) {
                monitor.beginTask(MakeUIPlugin.getResourceString("TargetBuild.monitor.beginTask"), targets.length); //$NON-NLS-1$
                try {
                    for (int i = 0; i < targets.length; i++) {
                        final IMakeTarget target = targets[i];
                        IWorkspaceRunnable runnable = new IWorkspaceRunnable() {

                            public void run(IProgressMonitor monitor) throws CoreException {
                                target.build(new SubProgressMonitor(monitor, 1));                               
                            }
                        };

                        MakeUIPlugin.getWorkspace().run(runnable, null, IResource.NONE, new SubProgressMonitor(monitor, 1));
                    }
                } catch (CoreException e) {
                    return e.getStatus();
                } catch (OperationCanceledException e) {
                } finally {
                    monitor.done();
                }
                return Status.OK_STATUS;
            }

            @Override
            public boolean belongsTo(Object family) {
                return ResourcesPlugin.FAMILY_MANUAL_BUILD == family;
            }           
        };

        // workaround for bug 270326, initialize CUIPlugin preference store to avoid race condition
        CUIPlugin.getDefault().getPreferenceStore().getString("dummy"); //$NON-NLS-1$
        targetJob.schedule();

    }
}

When the user clicks again the same kind of operation, it simply ignores the second request while running the first operation. It's my requirement and I think the IWorkspace.run() method is doing this (as far as I understand). The second operation is executing all the code but the IWorkspace.run() method.

I have tried adding a listener.

targetJob.addJobChangeListener(new JobChangeAdapter() {
public void done(IJobChangeEvent event) {
    if (event.getResult().isOK())
       System.out.println("Job completed successfully");
    else
       System.out.println("Job did not complete successfully");
    }
 });

targetJob.setSystem(true);

But when I click the menu operation the second time while running the first job, my execute() method of handler still calls buildTargets() and executes all the code without running the IWorkspace.run() method. My console prints end s.o.p. "Job completed successfully" for second click onwards.

So, If a user clicks the same operation second time onwards, I want to give a message to the user saying wait for the previous job to complete. How do I know the status of the first job running, so that I can give the message? I think I need to decide before creating the new job in buildTargets() method?

Thanks in advance!


Solution

  • I have used java.util.concurrent.locks.ReentrantLock to solve my problem. Thanks!