2007-02-26

Writing to the statusbar in Eclipse from a non-UI thread

If you are dealing with the UI in Eclispe and need access to a certian part, e.g. the Statusbar in this case, it is quite easily achieved. On the other hand if you would like to simply write a message to this afore mentioned status bar, it is a whole new deal. You wrie your code that in the end extracts the site in question. As you get hold of the current statusline manager from the site, this is the way to go. Or,..?. well, when you start to debug the code you find that you run into NullPointerExceptions. The site or its view parts are null. This happens if certain methods in e.g. JFace is called from a non-UI thread. It actually says so in the Javadoc, in some places. I.e. the getActiveWorkbenchWindow method in IWorkbench exposes this behaviour.

If you are to produce code that calls these methods but does not have a UI-thread available? Well, then we can create one. It is quite simple once you've got the hang of it. It might look a bit complicated at first as it comprises using an anonymous inner class (which is a bit of favorite of mine as they resemble, to some extent, closures - without being it - ok, let the comments come!). Below is a code snippet that will produce a message on the status line:

final Display display = Display.getDefault();

new Thread() {

public void run() {

display.syncExec(new Runnable() {
/*
* (non-Javadoc)
*
* @see java.lang.Runnable#run()
*/
public void run() {

IWorkbench wb = PlatformUI.getWorkbench();
IWorkbenchWindow win = wb.getActiveWorkbenchWindow();

IWorkbenchPage page = win.getActivePage();

IWorkbenchPart part = page.getActivePart();
IWorkbenchPartSite site = part.getSite();

IViewSite vSite = ( IViewSite ) site;

IActionBars actionBars = vSite.getActionBars();

if( actionBars == null )
return ;

IStatusLineManager statusLineManager =
actionBars.getStatusLineManager();

if( statusLineManager == null )
return ;

statusLineManager.setMessage( message );
}
});
}
}.start();

If you want to the clear the statusline, pass null as argument to the setMessage method. Too many method calls? I "chopped"them up a bit to make it clear. One does find code here and there in the open source community where the author has more or less kept the calls figuring out the site reference to one line.

There are few posts on EclipseZone about, or touching, the subject. One of the more intersting threads can be read here.

4 comments:

kengkaj said...

Do we need to use Thread?

Why not just use Display.getDefault().syncExec()?

R. Varttinen said...

Thank you for your comment.
The Thread thing was present in the example in the Eclipse FAQ so I let be in. Haven't tried doing it without the Thread yet (it was some time ago ... ). Have you tried? Can it be removed?

R. Varttinen said...

After a quick investigation I've found thatr the thread thing is required by the rendering in the underlying graphics. I.e. all communictaion with widgets etc. has to be done from within a UI-thread.

SriHarsha said...

Hi, thanks for your post.It was helpful.