以编程方式禁用菜单项

时间:2012-11-06 07:34:28

标签: java swing desktop-application netbeans-platform jmenuitem

我正在使用Netbeans RCP开发桌面应用程序。我有许多菜单项通过TopComponents中的注释添加到菜单中。 我希望能够禁用其中几个菜单项,具体取决于已登录用户的访问权限。

2 个答案:

答案 0 :(得分:4)

在NetBeans平台中执行此操作的一种方法是在菜单中注册Presenter.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
    }
}

当您在菜单中注册Presenter.Menu时,平台会调用getMenuPresenter()方法来获取添加到菜单中的实际JMenuItem

通常你只需在这里构建一个JMenuItem,但由于你需要能够在应用程序的其他部分中保留它,你需要保留一些菜单项的注册表,以便你将检索相同的实例。

一种方法是将所有ACL的菜单项注册为ServiceProvider。这样,当您需要启用/禁用所有这些时,您可以Lookup

ServiceProvider界面:

public interface ControllableMenuItem {

    void setEnabled(boolean enabled);

    JMenuItem getMenuItem();
}

ControllableMenuItem实施注册为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;
    }
}

现在,当您需要启用/禁用所有Lookup时,您可以ControllableMenuItem

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

然而,还有一件可以正常工作。您需要一种方法来保证Presenter.Menu获得与Lookup相同的实例。实现这一目标的一种方法 - 诚然不是很优雅 - 就是将MenuItem注册为@ServiceProvider,并在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();
    }
}

通过这种方式,只要Lookup ControllableMenuItem {{1}},您就可以获得相同的实例。

这只是这样做的一种方式。这里的要点是,当您需要禁用它们时,需要有一个机制来获取所有ACL'd菜单项的相同实例。

控制哪些菜单项实际进入菜单系统的另一种方法是为每个访问级别创建单独的模块,并在用户未获得特定功能组授权时简单地disable modules。这在许多方面都是有益的,并且是使用模块化系统的优势之一。

答案 1 :(得分:2)