Nifty Progress Reporting in RCP Applications
March 18, 2009 | 3 min ReadI don’t (always) like the ways Eclipse provides me to do long running operations. So I created another way with a nicer UI.
With the Jobs framework the Eclipse IDE provides some means for long running operations. The Jobs framework is able to run tasks in a parallel fashion and queue the rest, while providing user feedback with progress monitors. Other RCP applications have different needs when doing long running operations.
Specifically the Job frameworks UI feedback is not always what an RCP application wants. Sometimes I find that I’d rather prevent the user from clicking in the UI than queue more jobs. This happens for example if the user action triggers a network access that might take a while. There is no point in accepting the same user action again. So I want to provide a nice feedback mechanism to the user that their click is being processed.
Eclipse provides a progress monitor dialog. It’s a modal dialog that shows a process to the user and prevents her from clicking in the workbench. Personally, I don’t think it’s very appealing. Also, it’s not what I want… while I want some view being blocked often other views should stay operable.
I don’t know anything that means my use case from Eclipse so I created a few classes myself that take care of a presentable way to block workbench parts. Basically it’s a transparent shell that lays itself over a given control and displays a SWT ProgressIndicator widget. It responds to the controls re-size, move and disposal events… and looks quite neat! Way better than the progress modal dialog, and it leaves it up to the programmer which part of the UI should be blocked.
From the programmers point of view, I took the approach we find in Eclipse all the time: The programmer has to implement some “I..Runner” interface that is custom to my API. It contains a run method that takes an IProgressMonitor and is called outside the UI thread. My aim was to make the different steps during and after the long running operation as clear as possible to the programmer and reduce their need for inner classes. Unlike the Eclipse API I don’t think that it’s the users responsibility to sync back into the UI thread. This use case is common and creates unnecessary bloat in the source code. Therefore I provide 2 methods that are called within the UI thread after the operation is done, one for doing the actual feedback for the user and one for exception handling (if necessary). ```java public interface IResponsiveRunner {
/** * called from without the UI Thread */ public abstract void runOutsideUIThread( final IProgressMonitor monitor ) throws Exception;
/** * called after {@link #runOutsideUIThread(IProgressMonitor)} from within the UI Thread */ public abstract void uiFeedbackAfterRun();
/** * Called within the UI thread. This method is called if an error occurs during execute before * {@link #uiFeedbackAfterRun()} is called. * @param caught */ public abstract void handleException( final Exception caught ); } ``` This is what a programmer has to implement. Starting the nifty progress report is very similar to using a progress monitor dialog, instantiate and run:
java new NiftyProgress( myResponsiveRunner, new TransparentUIBlocker( control ) ).run();
The TransparentUIBlocker is the class that does the actual blocking. It’s passed in under a generic IUIBlocker interface that might have other implementations.
So, as a programmer, you provide an implementation of the IResponsiveRunner and point to a control that should be blocked, and you’re done. Nifty feedback to the user.
I attached a zip with plug-in projects with the classes and a small application that makes use of them. Use it, it’s EPL.
Oh, and if someone can tell me how to get notified if a view is hidden behind another one in a view stack, please do.