Dynamic menu contributions in Eclipse 4 - Guest blog by Marco Descher

2 minute read

While with the Juno Release, Eclipse 4 has become the new standard, there is still some functionality from Eclipse 3.x which is missing, at least when it comes to the developers view of things. With the upcoming Kepler release, however, this list is less one item, namely dynamic menu contributions.

In Eclipse 3 it was possible to add “dynamic” as an element to the org.eclipse.ui.menus contribution extension point for a given menu. This provided the capability to programmatically modify the entries offered within a menu, which is quite handy if one wants, for example, to alter the menu according to the given application context.

Eclipse bug 389063 brought the basic support and now with M6 some, but not all children’s diseases to the port are fixed (Bug 403083 and Bug 403081 did not make it in time for M6) and tooling support is provided as of 0.13. So it’s about time for a wrap up on the usage.

There are generally only three entities required to know:

  • the new model UI element DynamicMenuContribution
  • the new annotation @AboutToShow
  • the new annotation @AboutToHide

Let’s implement a simple dynamic menu contribution using the current Eclipse 4 tools for Kepler to demonstrate the usage.  

We start of by declaring a menu contribution for a menu located in the application main menu.

1_e4ToolingDynamic

Subsequently we use the provided wizard to generate a template for our dynamic menu contribution class.

2_newClassWizard

where we amend the existing @AboutToShow provided method with the following code. [sourcecode type=”java”] @AboutToShow public void aboutToShow(List items) { MDirectMenuItem dynamicItem = MMenuFactory.INSTANCE .createDirectMenuItem(); dynamicItem.setLabel("Dynamic Menu Item (" + new Date() + ")"); dynamicItem.setContributorURI("platform:/plugin/at.descher.test"); dynamicItem .setContributionURI("bundleclass://at.descher.test/at.descher.test.DirectMenuItem"); items.add(dynamicItem); } \[/sourcecode\]

The dynamicItem.setContributionURI(*) provides a simple handler which, on click of the menu element, outputs some random code.

package at.descher.test;

import org.eclipse.e4.core.di.annotations.Execute;

public class DirectMenuItem { 
	@Execute 
	public void execute() { 
		System.err.println("Direct Menu Item selected"); 
	} 
}

For the usage of @Execute check the following link.

If we now start the application, each time we open the respective menu we will see the current date.

So, the dynamic menu contribution hooks into the menus process of opening (AboutToShow) and closing (AboutToHide), and dynamically queries the method in order to populate the menu. It is important not to put any expensive code into the @AboutToShow annotated method, as this directly blocks the opening of the menu the dynamic contribution is child of.

Although the usage of @AboutToHide is optional, at the current M6 one has to provide such a method due to bug 403083. After 403081 is fixed it will be also possible to refactor the code presented above to this:


@AboutToShow 
public void aboutToShow(List<MMenuElement> items, EModelService modelService) { 
	MDirectMenuItem dynamicItem = modelService .createModelElement(MDirectMenuItem.class); 
	dynamicItem.setLabel("Dynamic Menu Item (" + new Date() + ")"); 
	dynamicItem.setContributorURI("platform:/plugin/at.descher.test"); 
	dynamicItem .setContributionURI("bundleclass://at.descher.test/at.descher.test.CommandHandler"); 
	items.add(dynamicItem); 
}

Thanks to Paul Webster for helping me to get this feature done! :)

Author: Marco Descher develops, and teaches students at the Fachhochschule Vorarlberg to develop, Eclipse based applications. If you want to know more about me just check out my homepage.

marco

Updated: