Jan Tacci
Jan Tacci

Reputation: 3201

Eclipse Plug-in Enable/Disable Menu Items Programatically

I am writing an eclipse plug-in that extends AbstractDebugView.

My plugin has one context menu item, one pull-down menu item, and one toolbar menu item. The action associated with these menu items is a class I created (CopyAction) which extends org.eclipse.jface.action.Action.

public class CopyAction extends Action {
    private String text;
    private String toolTipText;
    private boolean enabled;
    private ImageDescriptor imageDescriptor;
    ...    
    public CopyAction() {
        text = "Copy";
        toolTipText = "Copy Action";
        enabled = false;
        imageDescriptor = ...;
    }
    ...
    @Override
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }
    @Override
    public boolean isEnabled() {
        return enabled;
    }    
    ...
}

Note that by default my action is disabled (enabled = false).

In my plug-in main view class I create and add the copy action to each of the menus:

public class MyDebugView extends AbstractDebugView {
    CopyAction copyAction;
    ...
    @Override
    protected Viewer createViewer(Composite parent) {
        // do some stuff to create the viewer content
        createActions();
        fillLocalPullDown();
        ...
    }
    @Override
    protected void createActions() {
        copyAction = new CopyAction();
    }   
    private void fillLocalPullDown() {
        IActionBars bars = getViewSite().getActionBars();
        bars.getMenuManager().add(copyAction);
    }
    @Override
    protected void fillContextMenu(IMenuManager manager) {
        manager.add(copyAction);
    }   
    @Override
    protected void configureToolBar(IToolBarManager manager) {
        manager.add(copyAction));
    }    
}

Everything works great up to this point. When I test my plug-in I can see the context menu, the toolbar menu, and the pull-down menu.

All the menu items are disabled, as I would expect since the constructor for CopyAction sets enabled = false;

What I want to do is enable the menu items when a selection has changed in my plug-in view (which happens to be a TreeViewer). In the callback for the tree selection I do the following:

private class MySelectionChangedListener implements ISelectionChangedListener {
    public void selectionChanged(SelectionChangedEvent event) {
        // determine if the copy action should be enabled
        ...
        copyAction.setEnabled(true)
    }
}

The issue I am running into is that even though I set enabled to true on copyAction the menu items do not become enabled.

My suspicion as to what's happening is even though I set the enabled property to true nothing happens because the menu(s) need to be notified that the property has changed. Is there some method I have to call to force the menu managers to update themselves thereby checking the enabled property of the copy action?

====

I have been thinking about the way I have been coding my plug-in and researching the internet on how to add/enable/disable menu items to an Eclipse plug-in. Nearly all of the examples I have seen use plugin.xml to add the menu contributions instead of doing it programatically. (Most also use commands, not actions.) I have also seen where you can enable/disable/hide/show menus using property testers also configured in plugin.xml.

Should I just drop the way I am doing things now and do it using the plugin descriptor and property testers? I hate to throw away all the work I have done up to this point but it's more important for me to do it right rather than fuss over time spent.

Upvotes: 1

Views: 3118

Answers (1)

fredrik
fredrik

Reputation: 521

Add an IMenuListener that enables the context menu actions when the context menu is about to show:

    menuManager = new MenuManager();
    menuManager.setRemoveAllWhenShown(true);
    menuManager.addMenuListener(new IMenuListener() {
        public void menuAboutToShow(IMenuManager m) {
            contextMenuAboutToShow(m);
        }
    });
...

And then:

protected void contextMenuAboutToShow(IMenuManager m) {
    copyAction.setEnabled(copyAction.isEnabled());
    menuManager.add(copyAction);
    ...
}

Upvotes: 1

Related Questions