• Share this article:

Listenin’ to Parts

Tuesday, January 15, 2008 - 22:22 by Wayne Beaton

The Eclipse workbench contains a collection of stacked views and editors. Some views change their appearance based on the active editor. The Outline view is a good example of this: it changes its appearance (sometimes quite dramatically) when a different editor is activated. The workbench provides a handy mechanism that you can use to make your view do the same thing. All you have to do is provide an IPartListener (or an IPartListener2. Here’s the createPartControl method from a view that does just this:

public void createPartControl(Composite parent) {
	viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
	viewer.setContentProvider(new ViewContentProvider());
	viewer.setLabelProvider(new ViewLabelProvider());
	viewer.setInput(getActivePage().getActiveEditor()); /* 1 */

	partListener = new IPartListener() {
		private IWorkbenchPart activePart;
		public void partActivated(IWorkbenchPart part) {
			if (part instanceof IEditorPart) {
				activePart = part;
				viewer.setInput(part); /* 2 */
			}
		}

		public void partClosed(IWorkbenchPart part) {
			if (part == activePart) {
				activePart = null;
				viewer.setInput(null);
			}
		}
		...
	};
	getActivePage().addPartListener(partListener); /* 3 */
}

I’ve highlighted three lines in the code. The first highlight is were we set the input for the TableViewer to the currently active editor (if any). The input is passed to the content provider which is responsible for deciding what to display. This leads us to the second highlight. Here, we respond to a part being activated in the workbench. The part could be a view (instance of IViewPart) or an editor (instance of IEditorPart). If the activated part is an editor, it is given as input to the viewer which then uses the content provider to refresh itself with new information. You may also notice a that the partClosed method does something similar to make the view refresh to a “blank” state (as defined by the content provider).

The third bit of highlighted code shows how the part listener is added to the active page. Note that a corresponding dispose method is required to remove the listener when the view is closed.

The content provider for this example is pretty simple: it provides some rows containing pretty basic information about the active editor (or empty rows if the input is something other than an editor):

class ViewContentProvider implements IStructuredContentProvider {
	...
	public Object[] getElements(Object input) {
		if (input instanceof IEditorPart) {
			IEditorPart activeEditor = (IEditorPart)input;
			return new String[] {activeEditor.getTitle(), activeEditor.getTitleToolTip()};
		} else {
			return new String[] { };
		}
	}
}

The getActivePage method is a simple helper-method that just digs out the active workbench page from the site (the site is the glue between your view and the workbench):

private IWorkbenchPage getActivePage() {
	return getSite().getWorkbenchWindow().getActivePage();
}

I haven’t shown all the methods on IPartListener. There are other methods that are invoked when other types of things happen. There’s also a newer IPartListener2 that works the same way but can respond to more kinds of change.

Curiously, there is no “adapter” class for either of these listener interfaces. I’ve wondered why for a while, but haven’t bothered to ask. Any ideas?