Netbeans actions toolbar with local lookup context
This article talks about Netbeans and an action toolbar that is sensitive to a local selection lookup context. Actually, global selection context sensitive actions is powerful mechanism with a subtle limitation: everything happens globally. It is no use for a local actions menu or toolbar sensitive to a limited selection context restricted to a JPanel or TopComponent. Not surprisingly, the Netbeans Java IDE itself reinvents the wheel each time this requirement arises, for example, on the ‘variables’ and ‘breakpoint’ windows.
Thus, we still look forward for our local context to reuse conveniences like action annotations that prevent boilerplate code and extensibility through the layer.xml configuration.
Originally published at https://techtavern.wordpress.com.
We suppose that the JPanel or TopComponent owns a JToolbar that will hold all actions that apply to the local selection context. We recommend turning off the ‘floatable’ property, or the user may drag the toolbar out of the JPanel or TopComponent.
The solution relies on the convention that interested actions are to be declared under a pre-defined path within the layer.xml configuration. This allows any module to later provide further actions and works similar to the global toolbar convention itself. We have arbitrarily chosen to declare the actions under “TopComponentName/Toolbar”.
Actions for the local selection context are declared as any global action, except for the @ActionReference annotation, which references the previously pre-defined path instead of an entry in the global menu or global toolbar.
@ActionID(category = "category ",
id = "fully.qualified.name.of.LocalAction")
@ActionRegistration(
iconBase = "path/to/icon.png",
displayName = "#CTL_LocalAction")
@ActionReferences({
@ActionReference(path = "TopComponentName/Toolbar", position = 30)
})
@Messages("CTL_LocalAction=Action text")
public final class LocalAction implements ActionListener {
public LocalAction (Type context) {
...
}
@Override
public void actionPerformed(final ActionEvent ev) {
...
}
}
If fact, this action is global, as actions define a business procedure on a compatible context, regardless on which view or presentation, regardless if made available globally or locally.
Here is the code that populates a local toolbar:
List<? extends Action> actions = Utilities.actionsForPath("TopComponentName/Toolbar");
for (Action action : actions) {
if (action == null) {
toolbar.addSeparator();
} else {
if (lookup != null && action instanceof ContextAwareAction) {
action = ((ContextAwareAction) action).createContextAwareInstance(lookup);
}
Component item;
if (action instanceof Presenter.Toolbar) {
item = ((Presenter.Toolbar) action).getToolbarPresenter();
if (item == null) {
continue;
}
} else {
item = ActionPresenterProvider.getDefault().createToolbarPresenter(action);
}
toolbar.add(item);
}
}

