Replacing the Perspective-Switcher in RCP apps
For simple RCP Applications the Perspective-Switcher widget that ships with Eclipse is overloaded and cumbersome to use.
We are going to get rid of it and replace it with an equivalent menu and/or toolbar for switching perspectives. Both should have an indicator to show which perspective is currently active.
Hiding the Perspective-Switcher
To hide the Perspective-Switcher we go to our ApplicationWorkbenchWindowAdvisor and instruct the IWorkbenchWindowConfigurer to not show the perspective bar.
public void preWindowOpen() {
IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
configurer.setShowPerspectiveBar(false);
// ...
}
Using simple commands - not enough
Let’s see how we could contribute a menu / toolbar for switching perspectives.
The workbench has the command ‘org.eclipse.ui.perspectives.showPerspective’ that can switch to a given perspective. It accepts a parameter ‘org.eclipse.ui.perspectives.showPerspective.perspectiveId’ with the ID of the perspective to show. Optionally a second parameter ‘org.eclipse.ui.perspectives.showPerspective.newWindow’ will open the perspective in a new window if set to ’true’.
Using the ‘org.eclipse.ui.menus’ extension point we could contribute a menu with an appropriate
Unfortunately this approach has some drawbacks:
- long xml files
- the list of available perspectives is static - brittle and requires manual maintenance
- it is difficult to indicate which perspective is currently selected
Using dynamic contributions - success
Fortunately the
Here’s the
The class PerspectiveSwitcherMenu fills the menu on the fly.
We obtain the array of IPerspectiveDescriptors from the workbench. For each we create a MenuItem with the perspective’s icon and description. Since we created images, we have to dispose them when the menu item is disposed, using a dispose listener. A selection listener is in charge of switching perspective when a menu item is clicked. To provide indication about the active perspective we use the SWT.RADIO style and select one of the menu items. Since the menu is created on the fly each time it is used, we do not need to track the active perspective :-).
public class PerspectiveSwitcherMenu extends ContributionItem {
public void fill(Menu menu, int index) {
String activePerspective = getPerspectiveId();
IPerspectiveDescriptor\[\] perspectives = PlatformUI.getWorkbench().getPerspectiveRegistry().getPerspectives();
for(int i = 0; i < perspectives.length; i++) {
IPerspectiveDescriptor descriptor = perspectives\[i\];
// i is used as an item index; 0-n will add items to the top of the menu
MenuItem item = new MenuItem(menu, SWT.RADIO, i);
item.setData(KEY\_PERSPECTIVE\_DESCR, descriptor);
item.setText(descriptor.getLabel());
final Image image = descriptor.getImageDescriptor().createImage();
item.setImage(image);
item.addDisposeListener(new DisposeListener(){
public void widgetDisposed(DisposeEvent e) {
image.dispose();
}
});
item.addSelectionListener(menuListener);
if(descriptor.getId().equals(activePerspective)) {
item.setSelection(true);
}
}
}
public final boolean isDynamic() { return true; }
The toolbar contribution is very similar to the above. Using the ‘org.eclipse.ui.menus’ extension point, we add a
Since the toolbar is visible all the time, we have to track the active perspective, so we can update the ‘selected’ (=depressed) state of the toolbar buttons as necessary. This turned out to be quite tricky. Here’s the solution I went for: a listener tracking the active perspective is installed in each window. If the perspective changes, we look-up the toolbar and update the ‘selected’ state. Since windows may come and go, a second listener keeps track of window creation / disposal and installs / removes the perspective listener as necessary. I wish this was a bit easier - but I’m sharing the below code so you can save a bit of time on this.
Source Download
Download the full code here: example perspective switch.zip
Happy hacking, Elias.
PS: If you want to trade off more screen real-estate for a fancier switcher you can use a ‘standalone’ view or a composite that is placed around the page contents. Tom Seidel has the details on his blog.