Configuring and adding menu items in Eclipse V3.3

Use V3.3's new menu mechanism to accelerate plug-in and RCP development

In earlier versions of Eclipse, adding commands to a menu, pop-up menu, or toolbar was tricky. No more! Eclipse V3.3 introduces a mechanism that's easier than ever. Find out how to use the org.eclipse.ui.menus extension point.

Karsten Voigt (kvoigt@de.ibm.com), IT Architect, IBM

Karsten Voigt is IT architect and consultant for IBM Global Business Services in Germany. He mostly works for IBM customers in the automotive industry. His area of expertise is definition of integrative solutions for J2EE and Java rich-client applications, including Lotus Expeditor. In his spare time, he designs, develops, and uses applications on Java Swing and the Eclipse Rich Client Platform.



19 February 2008

Also available in Russian Japanese Portuguese

Menus, pop-up menus, and toolbars — almost every Eclipse plug-in or Eclipse Rich Client Platform (RCP) application requires these. Eclipse V3.3 introduced a feature that provides a more generic approach for configuring and adding menu items. This article illustrates how you can use the new menu mechanism to accelerate plug-in and RCP development.

In Eclipse V3.2 and earlier versions, you needed to use several extension points to add commands to a menu, pop-up menu, or toolbar. In fact, there were four different extension points: org.eclipse.ui.actionSets, org.eclipse.ui.viewActions, org.eclipse.ui.editorActions, and org.eclipse.ui.popupMenus. Unfortunately, every kind of contribution required its own extension point, and the action placement and visibility could not be separated.

Eclipse V3.3 introduces a new mechanism: org.eclipse.ui.menus. The extension point is the new way of placing menu items.

This article explains the new menu concepts and walks through the creation of a small Eclipse RCP application to cover most of the new features. You should have some basic skills using Eclipse RCP or the plug-in framework. The first step is to download an Eclipse distribution that has the Plug-in Development Environment (PDE) in it from Eclipse.org. I recommend downloading the latest version of Eclipse Classic. (See Resources to learn where to find Eclipse and additional background information if you are new to Eclipse.)

The platform command framework

Before we start implementing a plug-in that uses the new menu mechanism, we need to understand the command framework. A command is a declarative description of a component and is independent from the implementation details. A command can be categorized and a key binding can be assigned. With this approach, it is possible to define a generic key binding, and depending on the current context, we can choose a specific implementation. Figure 1 shows a simplified command class diagram.

Figure 1. Command class diagram
Command class diagram

Use the extension point org.eclipse.ui.commands for command definitions. Commands can also be created programmatically. To achieve this goal, we can use the ICommandService interface. Several handlers can handle a command, but only one handles a concrete runtime instance of the command. For integration in the Eclipse workspace, an image, menu items, and bindings can be assigned to a command. It is a good approach to group commands using categories. Categories ease the navigation in complex rich-client applications.


Adding a menu contribution

Let's begin using menu contributions. The example starts with implementing a small RCP application that has a single-menu entry. This menu entry just opens a message dialog. This small example illustrates the core concepts for using commands, handlers, and menus.

Create a new plug-in project called MenuContribution and set the Eclipse version to 3.3. Answer Yes to the question "Would you like to create a rich client application?" Use the Hello RCP template. The example is based on the package name com.ibm.de.eclipse.menu. All other settings can be kept as default. Now run the new project as Eclipse Application, and you will see the following window.

Figure 2. Hello RCP example
Hello RCP example

We will explain different menu contributions through this application. Open the plugin.xml, switch to Extensions, and add the org.eclipse.ui.commands extension. Since all commands should be grouped in a category, select the commands extension and create a new category by right-clicking New > category. Fill in the fields of the category, as shown in Figure 3.

Figure 3. Command category details
Command category details

Now add a new command within the commands extension by right-clicking New > command. Set the ID to com.ibm.de.eclipse.menu.command.testCmd, name it Test Command, and set the categoryId to com.ibm.de.eclipse.menu.command.cat1. For this command, we need a handler to execute the associated business logic. Add the extension point org.eclipse.ui.handlers and create a new handler. The commandId for the handler is com.ibm.de.eclipse.menu.command.testCmd. To create the handler class, click on the class link, which is shown in Figure 4. Figure 5 shows the wizard with the required parameters.

Hint: If you use the class link in several extensions, you create a new class that contains the required interfaces for the chosen extension point.

Figure 4. New handler class link
New handler class link
Figure 5. Wizard
Wizard

The handler must implement the method execute. Add the lines in Listing 1 to show a message dialog.

Listing 1. Handler execute method
public Object execute(ExecutionEvent event) throws ExecutionException {
	IWorkbenchWindow window = 
HandlerUtil.getActiveWorkbenchWindowChecked(event);
	MessageDialog.openInformation(
		window.getShell(), "MenuEclipseArticle Plug-in",
		"Hello, Eclipse world");
	return null;
}

Save the class, return to plugin.xml and save that file. Now create the menu contribution for the new command and handler. Add the org.eclipse.ui.menus extension and create a new menuContribution. The menu contribution has only one property named locationURI. This property defines the insertion point where the contained additions will be added. Use menu:org.eclipse.ui.main.menu as the locationURI. This URI defines a menu, which is placed in the standard Eclipse menu.

Until now, we have defined only the insertion point. To add a concrete menu, select the menu contribution and create a new menu. Set the label as TestMenu and use the ID com.ibm.de.eclipse.menu.test.

The last step is the definition of the link between the menu item and the predefined command. Click on TestMenu and add a new command. Set the commandId to com.ibm.de.eclipse.menu.command.testCmd and set the label to Do something. The extensions for your plugin.xml should look like what is shown in Figure 6. Before running the Eclipse application, open the class ApplicationWorkbenchWindowAdvisor, go to method preWindowOpen, and add the line configurer.setShowMenuBar(true);. Run the Eclipse application and test our new menu item.

Figure 6. All extensions overview
All extensions overview

The menu location URI

In the previous example, we defined a locationURI for the menu that adds the menu item directly to the applications menu bar, but the locationURI also supports other menu contributions. The following pattern characterizes menu insertion points: <scheme>:<menu-id>[?<placement-modifier>].

<scheme> menu
Add a contribution to the main menu or the menu for a view. The <menu-id> must point to an existing view ID or to the standard Eclipse menu org.eclipse.ui.main.menu. The <placement-modifier> enables the positioning of menu contributions using the pattern <placement>=<id>. For placements, the tags before or after can be used, and the <id> can be an existing separator name, menu ID, or item ID.
Hint: The class MenuUtil contains some common constant values for menu URIs.
<scheme> toolbar
Add a contribution to any toolbar. For this <scheme>, the <menu-id> can point to any view ID (for the views toolbar), org.eclipse.ui.main.toolbar, or any toolbar ID contained in the main toolbar. You can also use the <placement-modifier>.
<scheme> pop-up
Add a menu for registered context IDs and org.eclipse.ui.popup.any for all registered context menus. The <placement-modifier> can also be used.

Now let's extend our short example and use different types for menu contributions.


Adding a view and view contributions

Next, we extend the small application to contain a view with an action in the toolbar. We change the existing main menu action to open the view.

First, add the view extension point (org.eclipse.ui.views) and create a new view using the properties shown in Figure 7. Next, open the TestHandler and change the execution method to open the view.

Listing 2. Change the execute method to open the view
public Object execute(ExecutionEvent event) throws ExecutionException {
	try {
	HandlerUtil.getActiveWorkbenchWindow(event)
.getActivePage()
.showView("com.ibm.de.eclipse.menu.view.testview");
	} catch (PartInitException e) {
		throw new ExecutionException("Error while opening view", e);
	}
	return null;
}
Figure 7. Create view element details
Create view element details

We require, for that view, a new command and handler to add the proposed contributions. Create a new command and a new handler. Use the following properties; the handler must extend org.eclipse.core.commands.AbstractHandler. Use Listing 1 to implement the content of the handler execution method.

Table 1. Adding a new command and handler
Command or handlerDescriptionProperty
Commandidcom.ibm.de.eclipse.menu.command.viewCmd
nameView command
descriptionA view command example
categoryIdcom.ibm.de.eclipse.menu.command.cat1
HandlercommandIdcom.ibm.de.eclipse.menu.command.viewCmd
classcom.ibm.de.eclipse.menu.handler.ViewHandler

Now add two menu contributions. First, add a menuContribution (for the views menu bar) with URI menu:com.ibm.de.eclipse.menu.view.testview. The ID of the view is <menu-id>. Add a command directly to the menu with the commandId: com.ibm.de.eclipse.menu.command.viewCmd and the label Do something. Since we do not need a submenu structure, a menu for the menu contribution is not required. Also, add a menuContribution for the toolbar and use the URI toolbar:com.ibm.de.eclipse.menu.view.testview. For the toolbar, the command is referenced again, but you need to choose an icon. Use any of the default plug-in icons (e.g., icons/alt_window_16.gif). Run the application, execute the main menu command, and have a look at the opened view. The view should contain a toolbar and a menu with the proposed commands.

Figure 8. Example view with toolbar and menu contribution
Example view with toolbar and menu contribution

Adding a conditional pop-up contribution

Finally, we need to add a conditional pop-up contribution to the sample application. First, the view is extended to contain a list of elements. A context menu will be shown for these elements. Open the TestView class and change the createPartControl method.

Listing 3. Add a list and context menu to the TestView
public void createPartControl(Composite parent) {
	ListViewer lViewer = new ListViewer(new List(parent, SWT.MULTI));
	lViewer.setContentProvider(new ArrayContentProvider());
	lViewer.setInput(new String[] { "1", "2", "3", "4" });
		
	MenuManager menuMgr = new MenuManager();
	menuMgr.add(
new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
	getSite().registerContextMenu(menuMgr, lViewer);
		
	Control control = lViewer.getControl();
	Menu menu = menuMgr.createContextMenu(control);
	control.setMenu(menu);		
}

The standard ArrayContentProvider creates a ListViewer and shows just an array of strings. For this list, a MenuManager is created, and all content defined in the plugin.xml is added using the new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS). The context menu is registered to the site and attached to the control of the ListViewer.

Add the pop-up and conditional statement to plugin.xml. The context menu should be shown only if we select two elements in the list. Since this condition might be useful at several places in the plug-in, we use the extension org.eclipse.core.expressions.definitions to define a common rule. This extension is part of the org.eclipse.core.expression plug-in that has to be added as required by the plug-in. Go to the dependencies section of plugin.xml and add that plug-in. Go back the extension section and add org.eclipse.core.expressions.definitions. Set the id of the newly created definition to twoSelectedCheck. If no definition was created while adding the extension, create one. For this definition, add a with element and set the variable to activeMenuSelection. The with element specifies the variable name used for the check. If the variable cannot be resolved, an ExpressionException will be thrown while evaluating the rule.

Several standard variables are defined in Eclipse. For a complete list of available variables, review the Wikipedia definition of Command Core Expressions (see Resources). We use activeMenuSelection in the example. This variable is the selection available while a context menu is showing. Now add a count to the element and set the value to 2. The rule is defined that counts the active selected elements and returns true if two elements are selected. The plugin.xml for the definition should look like Listing 4.

Listing 4. Definition extension in the plugin.xml
<extension point="org.eclipse.core.expressions.definitions">
<definition id="twoSelectedCheck">
         <with variable="activeMenuSelection">
            <count value="2"></count>
         </with>
      </definition>
</extension>

After creating the definition, we add a new menu contribution. Go to the extension point org.eclipse.ui.menus and add a menu with locationURI pop-up: org.eclipse.ui.popup.any. Also add a command with commandIdcom.ibm.de.eclipse.menu.command.viewCmd for this menu. Until now, we have always seen the context menu. To toggle this behavior, add the visibleWhen element to the command. Next, add a reference element with definitionId twoSelectedCheck to the visibleWhen element. Finally, test the application. TestView now contains a list of elements. If two elements are selected, we may see a context menu.

Using the visibleWhen element in a plug-in's configuration file is a great way to restrict the visibility of menu contributions at design or runtime. We demonstrate that power in the example where we extend its use with another rule definition. TestView gets an additional text field, and the toolbar command is only available if the text field has the focus. First, extend the TestView with the code found in Listing 5. We use IFocusService to register the text field so the application can handle focus changes for the text field.

Listing 5. TestView with text field registered to IFocusService
public void createPartControl(Composite parent) {
	parent.setLayout(new FillLayout(SWT.VERTICAL));
		
	Text text = new Text(parent, SWT.BORDER);
		
	IFocusService focusService = 
(IFocusService) PlatformUI.getWorkbench()
.getService(IFocusService.class);
	focusService.addFocusTracker(text, "textControlId");
		
	ListViewer lViewer = new ListViewer(new List(parent, SWT.MULTI));
	...
}

The next step is the creation of a new definition. Go to org.eclipse.core.expressions.definitions and add a definition named focusDefinition with a with element using the variable activeFocusControlId. This variable contains the ID of the control that has the focus and was registered using IFocusService. Add an equals element with value textControlId. This rule returns true if the active component in focus has the ID textControlId. Listing 6 shows this definition in plugin.xml. Add this definition to a toolbar menu using visibleWhen with a reference element shown in Listing 7. Run and test the example.

Listing 6. Focus-control rule definition
<definition id="focusDefinition">
<with variable="activeFocusControlId">
     		<equals value="textControlId"></equals>
      </with>
</definition>
Listing 7. Toolbar menu contribution with visibleWhen
<menuContribution
locationURI="toolbar:com.ibm.de.eclipse.menu.view.testview">
      <command
      	commandId="com.ibm.de.eclipse.menu.command.viewCmd"
            icon="icons/alt_window_16.gif" label="Do something"
            tooltip="Do something">
            <visibleWhen>
            	<reference definitionId="focusDefinition"></reference>
            </visibleWhen>
      </command>
</menuContribution>

Conclusion

The new org.eclipse.ui.menus provides a useful way to define menu changes and additions in a consistent, clever manner. The only trick is in learning how to use the locationURI. In addition to the normal menu definition, you can define rules to enable the conditional visibility of menu entries. But what do we do with existing applications and plug-ins? The answer is easy: Migrate your applications to use the new mechanism. Why migrate? Some features of Eclipse that you rely on might not be available in upcoming releases. See Resources for more information regarding planned changes to menu contributions.


Download

DescriptionNameSize
Sample Perl scriptsos-eclipse-3.3menuContribution.zip65KB

Resources

Learn

Get products and technologies

Discuss

  • The Eclipse Platform newsgroups should be your first stop to discuss questions regarding Eclipse. (Selecting this will launch your default Usenet news reader application and open eclipse.platform.)
  • The Eclipse newsgroups has many resources for people interested in using and extending Eclipse.
  • Participate in developerWorks blogs and get involved in the developerWorks community.

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Open source on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Open source
ArticleID=289875
ArticleTitle=Configuring and adding menu items in Eclipse V3.3
publish-date=02192008