-
Notifications
You must be signed in to change notification settings - Fork 1
DevFaqDropdownMenuAddToolbarEnabled
Create an Action as described in the general FAQ for to add a dropdown menu to a toolbar.
In this case, your action also needs to implement ContextAwareAction. A ContextAwareAction is a factory for other Action instances which are tied to a specific Lookup (so that, if selection changes after the popup menu for a Node is shown, the Action does not operate on the wrong object). You can start with a subclass of javax.swing.AbstractAction, and you will need two constructors:
private final Lookup lookup;
public MyAction() {
this (Utilities.actionsGlobalContext());
}
private MyAction(Lookup lookup) {
this.lookup = lookup;
Icon icon = ImageUtilities.image2Icon(
ImageUtilities.loadImage("com/foo/icon.gif"));
putValue(SMALL_ICON, icon);
//set the initial enabled state
setEnabled(false);
}
You will also need to implement the one method of ContextAwareAction:
public Action createContextAwareInstance(Lookup actionContext) {
return new MyAction(actionContext);
}
To enable and disable the action, we will need to listen on the lookup for the presence or absence of some object type. If it is there, the action will be enabled; if it is not, it will be disabled.
Since we do not want to start listening on the global selection context until something actually cares whether the action is enabled or not, so we will override add/removePropertyChangeListener() to notice that and listen or not.
First, we must modify our class signature to implement LookupListener:
public class MyAction extends AbstractAction implements ContextAwareAction, LookupListener, Presenter.Toolbar {
...
Now we will handle listening on the Lookup.Result. We want to stop listening to it when there are no PropertyChangeListeners left, so that our action can be garbage collected if not in use:
private LookupResult<? extends DataObject> res;
@Override
public synchronized void addPropertyChangeListener(PropertyChangeListener l) {
boolean startListening = getPropertyChangeListeners().length == 0;
super.addPropertyChangeListener(l);
if (startListening) {
res = lookup.lookupResult(MyType.class);
res.addLookupListener(this);
}
}
@Override
public synchronized void removePropertyChangeListener(PropertyChangeListener l) {
super.removePropertyChangeListener(l);
if (getPropertyChangeListeners().length == 0) {
res.removeLookupListener(this);
res = null;
}
}
Now comes the actual implementation of LookupListener:
public void resultChanged(LookupEvent ev) {
setEnabled(!res.allItems().isEmpty());
}
A bit of bookkeeping is required in getToolbarPresenter() - at least until issue 179814 is fixed, we will need to manually enable/disable the actions for our menu items:
private final Set<Action> popupMenuActions = new WeakSet<Action>();
@Override
public Component getToolbarPresenter() {
JPopupMenu menu = new JPopupMenu();
Action actionOne = new DemoMenuAction("One");
Action actionTwo = new DemoMenuAction("Two");
menu.add(new JMenuItem(actionOne));
menu.add(new JMenuItem(actionTwo));
popupMenuActions.add(actionOne);
popupMenuActions.add(actionTwo);
//add action listeners to the menu items to do what you want
Icon icon = (Icon) getValue(SMALL_ICON);
JButton result = DropDownButtonFactory.createDropDownButton(icon, menu);
result.setAction(this);
return result;
}
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
for (Action a : popupMenuActions) {
if (a != null) { //WeakSet iterator can return null
a.setEnabled(enabled);
}
}
}
private class DemoMenuAction extends AbstractAction {
DemoMenuAction(String name) {
putValue(NAME, name);
setEnabled (MyAction.this.isEnabled());
}
@Override
public void actionPerformed(ActionEvent e) {
DataObject ob = res.allInstances().iterator().next();
DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(
ob.getName()));
}
}
If we want the drop-down button to do something when it is clicked on the right side (not in the popup area with the down-arrow), we can implement actionPerformed(ActionEvent) to do whatever that is.
For an older detailed example of manually creating a context-aware drop-down toolbar button (without DropDownButtonFactory, circa NetBeans 6.0), see see this post, posted in on the old dev@openide NetBeans mailing lists.
The content in this page was kindly donated by Oracle Corp. to the Apache Software Foundation.
This page was exported from http://wiki.netbeans.org/DevFaqDropdownMenuAddToolbarEnabled , that was last modified by NetBeans user Jtulach on 2010-07-24T20:35:21Z.
NOTE: This document was automatically converted to the AsciiDoc format on 2018-01-26, and needs to be reviewed.
Apache NetBeans is an effort undergoing incubation at The Apache Software Foundation (ASF).
Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making process have stabilized in a manner consistent with other successful ASF projects.
While incubation status is not necessarily a reflection of the completeness or stability of the code, it does indicate that the project has yet to be fully endorsed by the ASF.
This wiki is an experiment pending Apache NetBeans Community approval.