Eclipse RCP Dynamic popup menu

I do not have a lot of experience with the Eclipse Rich Client Platform (RCP), yet I was asked to create a dynamic submenu for an element in a JFace TreeView. The submenu should be filled in depending on the selected object plus a fixed menu item which should open a new dialog. The menu should be hidden if the selected object has a value set for the property ‘myProperty’.
I’ve struggled for days to get this working, especially since most solutions on the internet referred to the MenuManager which didn’t work at all in my case.

Fortunately, after some trial and error I managed to set up the submenu using the standard plugin extensions.

The fixed command

First thing to define is the fixed command which will open a new dialog.

Under the org.eclipse.ui.commands extention point, add the following command definition

      <command defaultHandler="be.x.y.z.AddToHandler" id="be.x.y.z.addTo" name="Add to ..">

The corresponding handler class is fairly simple, it’ll just open a new dialog while passing the selected item to this dialog.

import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.commands.IHandlerListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.handlers.HandlerUtil;

public class AddToHandler implements IHandler {

  public void addHandlerListener(final IHandlerListener handlerListener) {

  public void dispose() {

  public Object execute(final ExecutionEvent event) throws ExecutionException {
    ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event).getActivePage().getSelection();
    MyObject myObject = SelectionEval.singleton(selection, MyObject.class);
    MySearchDialog gds = new MySearchDialog(HandlerUtil.getActiveWorkbenchWindow(event).getShell(), myObject);;
    return null;

  public boolean isEnabled() {
    return true; // set to true to make it always visible

  public boolean isHandled() {
    return true; // set to true to make it always visible

  public void removeHandlerListener(final IHandlerListener handlerListener) {


Testing the selected object

Next step is to define a property tester which will check if the selected object satisfies all conditions to show the menu.

The following property tester should be defined in the org.eclipse.core.expressions.propertyTesters extension point:

      <propertyTester class="be.x.y.z.addToPropertyTester" id="be.x.y.z.addToPropertyTester" namespace="be.x.y.z.addToPropertyTester" properties="myProperty" type="java.lang.Object">

The property tester itself is fairly simple and does nothing but a null-check

import org.eclipse.core.expressions.PropertyTester;
import be.x.y.z.MyObject;

public class AddToPropertyTester extends PropertyTester {

  public boolean test(final Object receiver, final String property, final Object[] args, final Object expectedValue) {
    if (property.equals("myProperty") && receiver instanceof MyObject) {
      MyObject myObject = (MyObject) receiver;
      return myObject.getMyProperty() == null;
    return false;


Adding menu items dynamically

Adding items using a dynamic menu requires an instance of a ContributionItem.

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import org.eclipse.jface.action.ContributionItem;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.ui.PlatformUI;

public class AddToContributionItem extends ContributionItem {

  public void fill(final Menu menu, final int index) {
    super.fill(menu, index);
    ISelection is = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getSelection();
    MyObject singleton = SelectionEval.singleton(is, MyObject.class);
    if (singleton == null) {

    Map<string, map<string,="" object="">> data = new TreeMap<>();
    // Some logic to fill in data

    int count = 0;
    for (Entry<string, map<string,="" object="">> entry : data.entrySet()) {
      if (++count > 15) {	// Limit number of items to 15
      MenuItem menuItem = new MenuItem(menu, SWT.NONE, index);
      menuItem.setData("OBJECT_DATA", entry.getValue().get("OBJECT_DATA"));	// you can store extra data here, which you can use in the selection listner
      menuItem.addSelectionListener(new SelectionAdapter() {

        public void widgetSelected(final SelectionEvent e) {
          MyData dO = (MyData) e.widget.getData("OBJECT_DATA");
          // Whatever you want to do


Glueing it all together

Last step is to glue everything together in an org.eclipse.ui.menus extension point:

      <menuContribution allPopups="false" locationURI="popup:org.eclipse.ui.popup.any"> <!-- This is the menu contribution for the "add to" menu --></pre>
<menu id="be.x.y.z.addtomenu" label="Add to"> <!-- This is the menu item which <span class="hiddenSuggestion" pre="which " data-mce-bogus="1">contains</span> a sub menu -->

            	<!-- This is the dynamic part of the menu -->
            <command id="be.x.y.z.addToMenuContribution" label="..."></command>	<!-- This command will open the search dialog -->
                <!-- Use the isHandled() and isEnabled() method to show or hide this fixed menu item) -->

            	<!-- This is the fixed menu item which opens a new search dialog -->
            	<!-- Only show the menu if *selection*.count == *1* AND *selection*[O] instanceof MyObject AND *selection*[O] has no myProperty -->

                         <!-- Important, this is the property tester namespace + property -->

                  	<!-- Make sure we have selected only 1 single object -->



Disclaimer: I’m not an Eclipse RCP expert and even though this might work, it’s probably not the most efficient way to do this, especially because we’re binding it to popup:org.eclipse.ui.popup.any, however, it was to only way I could get this working in our somewhat bloated project.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s