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);
  }
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: