6 min read

(For more resources related to this topic, see here.)

How to do it…

  1. Open the application model (Application.e4xmi) and go to Application | Windows | Trimmed Window | Controls | Perspective Stack | Perspective | Controls | PartSashContainer | Part ( Code Snippets).
  2. Expand the Code Snippet part and right-click on the Menus node.
  3. Select Add child | Popup Menu. Set the ID of the pop-up menu to codesnippetapp.snippetlist.popupmenu.
  4. Right-click on the newly added pop-up menu and select Add Child | DirectMenuItem.
  5. Set Label of the menu item as New Snippet.
  6. Click on Class URI link. This opens the New Handler wizard.
  7. Click on the Browse button next to the Package textbox and select codesnippetapp.handlers from the list of packages displayed.
  8. Set Name as NewSnippetMenuHandler and click on the Finish button. The new class file is opened in the editor. Go back to the application model. Refer to the following screenshot:

  9. Right-click on the Popup Menu node and add another pop-up menu item with the Delete label and the DeleteSnippetMenuHandler class.
  10. Now we need to register this pop-up menu with the TableViewer class in the Code Snippets part. Open the class SnippetListView (you can find this class in the codesnippetapp.views package). We will have to register the pop-up menu using Menu Service.
  11. Add the EMenuService argument to the postConstruct method:

    @PostConstruct
    public void postConstruct(Composite parent, IEclipseContext ctx,
    EMenuService menuService)

    
    
  12. Append the following code to the postConstruct method:

    menuService.registerContextMenu(snippetsList.getTable(),
    “codesnippetapp.snippetlist.popupmenu”);

    
    
  13. Run the application. Right-click in the TableViewer class on the left-hand side. You should see a pop-up menu with two options: New Snippet and Delete.

How it works…

To add a pop-up menu, you first need to create a menu in the application model for a part in which you want to display the menu. In this recipe, we added a menu to the Code Snippets part.

Then, you add menu items. In this recipe, we added two DirectMenuItem. For the main menu bar in the task of adding menu and toolbar buttons, we added HandledMenuItem, because we wanted to share the handler for the menu between toolbar button and menu item. However, in this case, we need only one implementation of options in the pop-up menu, so we created DirectMenuItem. But, if you want to add keyboard shortcuts for the menu options, then you may want to create HandledMenuItem instead of DirectMenuItem.

For each menu item, you set a class URI that is a handler class for the menu item.

The next step is to register this pop-up menu with a UI control. In our application, we want to associate this menu with the TableViewer class that displays a list of snippets. To register a menu with any UI control, you need to get an instance of EMenuService. We obtained this instance in the postConstruct method of SnippetListView using DI—we added the EMenuService argument to the postConstruct method.

Then, we used registerContextMenu of EMenuService to associate the pop-up menu with the TableViewer class. registerContextMenu takes instances of the UI control and menu ID as arguments.

There’s more…

The Delete option in our pop-up menu makes sense only when you click on any snippet. So, when you right-click on an area of TreeViewer that does not have any snippet at that location, the Delete option should not be displayed, only the New Snippet option.

This can be done using core expressions. You can find more information about core expressions at http://wiki.eclipse.org/Platform_Expression_Framework, and http://wiki.eclipse.org/Command_Core_Expressions.

We will use a core expression to decide if the Delete menu option should be displayed. We will add a mouse listener to the TableViewer class. If the mouse was clicked on a Snippet, then we will add SnippetData to IEclipseContext with the snippet_at_mouse_click key. If there is no snippet at the location, then we will remove this key from IEclipseContext.

Then, we will add a core expression to check if the snippet_at_mouse_click variable is of type codesnippetapp.data.SnippetData. We will then associate this core expression with the Delete menu item in the application model.

Adding mouse listener to the TableViewer class

  1. Create a static field in the SnippetListView class.

    private static String SNIPPET_AT_MOUSE_CLICK = “snippet_at_mouse_
    click”;

    
    
  2. Make the ctx argument of the postConstruct method, final.
  3. Append the following code in the postConstruct method:

    //Add mouse listener to check if there is a snippet at mouse click
    snippetsList.getTable().addMouseListener(new MouseAdapter() {
    @Override
    public void mouseDown(MouseEvent e)
    {
    if (e.button == 1) //Ignore if left mouse button
    return;
    //Get snippet at the location of mouse click
    TableItem itemAtClick = snippetsList.getTable().
    getItem(new Point(e.x, e.y));
    if (itemAtClick != null)
    {
    //Add selected snippet to the context
    ctx.set(SNIPPET_AT_MOUSE_CLICK, itemAtClick.getData());
    }
    else
    {
    //No snippet at the mouse click. Remove the variable
    ctx.remove(SNIPPET_AT_MOUSE_CLICK);
    }
    }
    });

    
    

Creating core expression

Carry out to the following steps:

  1. Open plugin.xml and go to the Dependencies tab.
  2. Add org.eclipse.core.expression as a required plugin.
  3. Go to the Extensions tab. Add the org.eclipse.core.expressions. definitions extension. This will add a new definition. Change the ID of the definition to CodeSnippetApp.delete.snippet.expression.
  4. Right-click on the definition and select New |With. Change the name of the variable to snippet_at_mouse_click. This is the same variable name we set in the SnippetListView class.
  5. Right-click on the With node, and select New | instanceof option. Set the value to codesnippetapp.data.SnippetData.

    This core expression will be true when the type of (instanceof) the snippet_at_mouse_click variable is codesnippetapp.data.SnippetData.

  6. Click on plugin.xml and verify that the core expression definition is as follows:

    <extension point=”org.eclipse.core.expressions.definitions”> <definition id=”CodeSnippetApp.delete.snippet.expression”> <with variable=”snippet_at_mouse_click”> <instanceof value=”codesnippetapp.data.SnippetData”> </instanceof> </with> </definition> </extension>

    
    

Setting the core expression for Menu Item

  1. Open the application model (Application.e4xmi) and go to DirectMenuItem for the Delete pop-up menu.
  2. Right-click on the menu item and select Add child | VisibleWhen Core Expression. This will add a Core Expression child node.
  3. Click on the Core Expression node and then on the Find button next to the Expression Id textbox and select CodeSnippetApp.delete.snippet. expression from the list. This is the ID of the core expression definition we added in plugin.xml.

Run the application. When you right-click on the Snippets List view, which does not have any snippet at this point, you should see only the New Snippet menu option.

Summary

In this task, we created a pop-up menu that is displayed when you right-click in the snippets list. If no snippet is selected at a location where you right-click, then it displays a pop-up menu with a single option to add a snippet. If there is a snippet at the location, then we display a menu that has options to delete the snippet and add a snippet.

Resources for Article :


Further resources on this subject:


LEAVE A REPLY

Please enter your comment!
Please enter your name here