Dynamic menu contributions

Bug 389063 introduced dynamic menu items within the Eclipse 4 application model. Today Paul Webster pushed the commit to platform.ui so it is ready to show starting with tonights integration build or the upcoming Kepler M4.

But what is it, and how to use it? During development I started a sample project on called at.descher.eclipse.bug389063 that is the first to take usage of the new feature. It is accessible on my github repository.

Generally, dynamic menu contributions are added to a menu just like other elements of the form HandledMenuItem or DirectMenuItem. But instead of representing only one element they can be instantiated dynamically by anything your code wants it to show. This is similar to the dynamic menu contribution one could add in Eclipse 3.x using the org.eclipse.ui.menus extension point.

Corresponding to the Eclipse application model you now have to insert a respective menu:DynamicMenuContribution element, an example is shown in the following code snippet:

<children xsi:type="menu:DynamicMenuContribution"
       xmi:id="_JTeEkAp4EeK8ULSwuUCzow" elementId="at.descher.dmc.0"
       label="irrelevantLabelWillNotBeShown"
       contributionURI="bundleclass://at.descher.eclipse.bug389063/
        at.descher.eclipse.bug389063.dynamic.DynamicMainMenuContribution" />
 

Here one can see the reference to the contributionURI which is the class responsible to provide the Dynamic Menu Elements. There are two new annotations available which are evaluated within such contribution classes:

  • @AboutToShow the method carrying this annotation is called when the menu is about to open
  • @AboutToHide the method carrying this annotation is called when the menu is about to close

In order to provide an example I take an excerpt of the respective methods from the class DynamicMainMenuContribution class:

@AboutToShow
public void aboutToShow(List<MMenuElement> items) {
 MDirectMenuItem dynamicItem = MMenuFactory.INSTANCE
   .createDirectMenuItem();
  dynamicItem.setLabel("Dynamic Menu Item (" + new Date() + ")");
  dynamicItem
    .setContributorURI("platform:/plugin/at.descher.eclipse.bug389063");
  dynamicItem
    .setContributionURI("bundleclass://at.descher.eclipse.bug389063/
         at.descher.eclipse.bug389063.dynamic.DirectMenuItemAHandler");
items.add(dynamicItem);

In @AboutToShow an empty list, namely items gets injected. It is to be populated by the developer. The above example shows the addition of a simple MDirectMenuItem which is handled by the DirectMenuItemAHandler class.

Caution Do not put code with a long execution time within this method, as this directly blocks the opening process of the menu, and may look to the user as though the system crashed.

Providing an @AboutToHide method is optional, if one wants to say so, if however one has a reason to use it, the framework takes care about injecting the list populated during @AboutToShow into this method. So the following example shows that the list is not empty, and uses the @AboutToHide annotated method to simply increase a counter.

@AboutToHide
public void aboutToHide(List<MMenuElement> items) {
 System.out.println("aboutToHide() items-size: " + items.size());
 addSecond = !addSecond;
}

There does not yet exist support for the Application Model Editor, but I am working on it. As soon as there is news, I’ll present it here :)

Remark Recently I found out about two problems using this dynamic contribution, I already filed the respective Eclipse Bugs in 398866 and 398865.