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.

- 37,241
- 25
- 195
- 267

- 1,279
- 4
- 19
- 38
-
2*" So far, although the question has been asked a number of items over the forums, I haven´t found a satisfying solution."* Link to the top 3 solutions and explain why they do not work for your use-case. – Andrew Thompson Nov 06 '12 at 08:07
-
https://www.google.de/search?q=disable+menu+at+runtime+netbeans+RCP, i looked through the first 3 pages, couple of dead links, some plainly unanswered, most are slightly off-topic for me. This one looked promising: http://netbeans-org.1045718.n5.nabble.com/enable-disable-menubar-during-runtime-td3035568.html ,but I haven´t managed to get it to work. – Jannis Alexakis Nov 07 '12 at 08:20
2 Answers
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 ControllableMenuItem
s 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 ControllableMenuItem
s.
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.

- 7,682
- 2
- 34
- 41
see Oracle tutorial How to Use Menus, run code examples
use
Xxx.setEnabled(false)
forJMenu
,JMenuItem
,JRadioButtonMenuItem
andJCheckBoxMenuItem

- 109,525
- 20
- 134
- 319
-
3I would also recommend looking at the `Action` & `AbstractAction` classes. – Andrew Thompson Nov 06 '12 at 08:08
-
I am familiar with xxx.setEnabled(boolean) and the Swing components you are mentioning. Only, the menu items are beeing generated on startup by the Netbeans RCP (layer.xml), according to the annotations of the TopComponent classes. There aren´t any JMenus to manipulate, except if you know a way to call on these generated menu items, which would definitely answer my question. – Jannis Alexakis Nov 07 '12 at 08:08
-
1. refuse GUI generator and to create JMenuBar, JMenu and JMenuItems by your hand, 2. have to keep JMenuItems for each of userprofile in separate array , 3. really crazy way (never used any GUI generator in VBA, C/++ or Java) have to derive JMenuBar and its Items from JFrame, then Iterating inside JMenuItems, – mKorbel Nov 07 '12 at 08:16
-
That´s how I have been doing it so far (your points 1 and 2). But: I just want to know if there is any way, using the RCP tools, to manipulate the menu items at runtime. – Jannis Alexakis Nov 07 '12 at 08:26
-
disadvantage (no deepest knowledge, but never ending story here) is that part of methods are protected, not accesible from methods, result for you not able to change, for those reasons there are properties windows for every elements in the GUI, there you have to set required methods or to add custom code block, sorry no idea how that works – mKorbel Nov 07 '12 at 08:38