Disable menu items programmatically

試著忘記壹切 提交于 2019-12-14 04:19:36

问题


I am working on a Desktop app with the Netbeans RCP. I have a number of menu items that are beeing added to the menu through annotations in the TopComponents. I would like to be able to disable several of these menu items, depending on the access rights of the logged user.


回答1:


One way to do this in the NetBeans Platform is to register a Presenter.Menu in the menu:

@ActionID(id = "com.company.MyPresenter", category = "Edit")
@ActionRegistration(displayName = "com.company.Bundle#CTL_MyPresenter")
@ActionReference(path = "Menu/Edit", position = 1)
public class MyPresenter implements Presenter.Menu {

    @Override
    public JMenuItem getMenuPresenter() {
        // return menu item from your ACL'd registry
    }
}

When you register a Presenter.Menu in the menu the getMenuPresenter() method is called by the platform to get the actual JMenuItem that is added to the menu.

Normally you would just construct a JMenuItem here but since you need to be able to get a hold of it in other parts of the application you'll need to keep some kind of registry of your menu items so that you'll be retrieving the same instance.

One way to do this is to register all of your ACL'd menu items as a ServiceProvider. In this way you can Lookup all of them when you need to enable/disable them.

A ServiceProvider interface:

public interface ControllableMenuItem {

    void setEnabled(boolean enabled);

    JMenuItem getMenuItem();
}

A ControllableMenuItem implementation registered as a ServiceProvider:

@ServiceProvider(service = ControllableMenuItem.class)
public class MyMenuItem implements ControllableMenuItem {

    private JMenuItem menuItem;

    @Override
    public void setEnabled(boolean enabled) {
        getMenuItem().setEnabled(enabled);
    }

    @Override
    public JMenuItem getMenuItem() {
        if (menuItem == null) {
            menuItem = new JMenuItem(new MyAction());
        }
        return menuItem;
    }
}

Now you can Lookup all of the ControllableMenuItems when you need to enable/disable them:

Collection<? extends ControllableMenuItem> menuItems = 
    Lookup.getDefault().lookupAll(ControllableMenuItem.class);
for (ControllableMenuItem item : menuItems) {
    item.setEnabled(isAuthorized());
}

However there's one more piece for this to work properly. You need a way to guarantee that the Presenter.Menu is getting the same instance that the Lookup is getting. One way to do this - admittedly not very elegant - is to register the MenuItem as a @ServiceProvider for itself and look this up in getMenuPresenter():

// replaces the above annotation of MyMenuItem
@ServiceProviders(value = {
    @ServiceProvider(service = ControllableMenuItem.class),
    @ServiceProvider(service = MyMenuItem.class)
})
public class MyMenuItem implements ControllableMenuItem {...}

public class MyPresenter implements Presenter.Menu {

    @Override
    public JMenuItem getMenuPresenter() {
        MyMenuItem myMenuItem = Lookup.getDefault().lookup(MyMenuItem.class);
        return myMenuItem.getMenuItem();
    }
}

In this way you are guaranteed to get the same instance whenever you Lookup your ControllableMenuItems.

This is only one way of doing this. The point here is that you need to have a mechanism in place to get the same instances of all of your ACL'd menu items when you need to disable them.

Another approach to controlling what menu items actually make it into the menu system is to create separate modules for each level of access and simply disable modules when users aren't authorized for a particular group of functionality. This is beneficial in many respects and is one of the strengths of using a modular system.




回答2:


  • see Oracle tutorial How to Use Menus, run code examples

  • use Xxx.setEnabled(false) for JMenu, JMenuItem, JRadioButtonMenuItem and JCheckBoxMenuItem



来源:https://stackoverflow.com/questions/13246428/disable-menu-items-programmatically

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!