Eclipse Rich Client Platform - Updating the status bar

For a current project, after evaluating the various platforms available, I decided to use Eclipse's Rich Client Platform (RCP) . As with any new framework the size of Eclipse RCP, the learning process can be a stop-start affair and I wished to capture some of the most problematic parts of learning this new framework before they become distant memories. As with any framework once you understand it, it looks obvious with hindsight, but is definitely not the case in the beginning.

Eclipse RCP API maze

Once of the most frustrating thigs with Eclipse RCP is the, seemingly, myriad of ways of getting references to essentially globally available objects.  If you are stuck for a reference to a view, manager or control you can try anyone of the following global objects Platfrom, PlatformUI, HandlerUI or Activator, as well as many method of the class you are subclassing eg AbstractView, AbstractHandler etc. With my current understanding its a hit and miss affair finding the reference you need. I can see the difference between Platform and PlatformUI but as for the Activator and PluginUI I have no reason to pick the one over the other to get a reference to a Workbeanch for example. Even then there are confusing methods like getDisplay which seems to pop up all over the place, while there seems to be several ways to get a view reference.  I assume that they all return references to the same thing? but who knows. By next week it will all be obvious to me. (I hope.)

Updating the RCP Status Bar

I have come across a particular example of the confusion I face at the moment with the platform that I wish to document for prosperity. The problem is updating the status line for an Eclipse RCP application. From the various tutorials I have read this is, apparently a trivial matter. (See one such tutorial here). However from my experience this is not the case.

According to the tutorial putting the update to the status line in the postWindowCreate method is used to demonstrate the ease with which the status bar can be updated and the following code does indeed work. The status bar needs to be enabled first with a call to  "configurer.setShowStatusLine(true);" in the preWindowCreate method. (This is all in the tutorials available online see link above.)

    @Override
    public void postWindowCreate() {
        super.postWindowCreate();
        this.getWindowConfigurer().getActionBarConfigurer().getStatusLineManager().setMessage("Test!");
    }

 Obviously updating a status line in the postWindowCreate purpose is pretty much not the way a real application would do it but the principle should apply. So I want to update the status line after a Job, which is essentially an enhanced background thread, is completed. I created a method in my view class to update the status line.

    public void updateStatusBar(){
            IStatusLineManager statusLine = this.getViewSite().getActionBars().getStatusLineManager();
            StringBuffer buf = new StringBuffer("Batch Totals: file count:");
           buf.append(NumberFormat.getInstance().format(Controller.getController().getBatch()
             .getTotalNumberOfFiles())).append (" file size:");
            buf.append(NumberFormat.getInstance().format(Controller.getController().getBatch().getTotalFileSize()));
            statusLine.setMessage(buf.toString());
    }

Calling it from a a job thread with the appropriate wrapping to ensure the call is made on the UI thread fails (see method below). As a test I tried calling this method at the end of the view's overridden "createPartControl" method but it failed to update the status line.

    public static void updateBatchStatistics(final Node node,final NodeActionType type){
        Job updateBatchStatisticsJob = new Job("Updating batch statistics..."){
            @Override
            protected IStatus run(IProgressMonitor monitor) {
                monitor.beginTask("Updating batch stats",IProgressMonitor.UNKNOWN);
                Controller.getController().getBatch().updateFileCountAndSize(node, type);
                monitor.done();
                return Status.OK_STATUS;
            }
    };
    updateBatchStatisticsJob.schedule();
    updateBatchStatisticsJob.addJobChangeListener(new JobChangeAdapter(){
            public void  done(IJobChangeEvent event){
                if (event.getResult()==Status.OK_STATUS)
                        PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable(){
                        public void run(){
                            BatchView view = (BatchView) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView(BatchView.ID);
                            view.updateStatusBar();                       
                            }
                    });
               
            }
        });
    }        

This represents the current state of my attempt to get the view to update the status bar. Getting to this point is another whole story! For example trying to find a method that could return a view was a mission. At first I tried something like         "PlatformUI.getWorkbench().getViewRegistry().find(BatchView.id)" but this kept on returning a classcast exception when I tried to cast the view to BatchView. After some auto-completion educated guesses I arrived at 

PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView(BatchView.ID);

I have no idea why the one approach throws an exception and the other doesn't and this is one of the points I am trying to make about the UI. It is very confusing as it seems quiet arbitrary, although I am sure its not.

When I find a solution I will be sure to post it as my googling shows there are several people who have had this problem but the solution always seems to be "it works for me".

Comments

Hi,

I couldn't take help of above code. Could you please help me out ? I have "OpenProjectDilog.java" which extends Dialog from where i have code to open project. Once i click on "Opne" button , in status bar , i want status "You are working on :"+projectName like this. Could you please provide me some sample code to implement it.