blob: 0b80ec58be6d69d31831971b8a87bb97d2883bdf [file] [log] [blame]
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
= DevFaqDropdownMenuAddToolbarEnabled
:jbake-type: wiki
:jbake-tags: wiki, devfaq, needsreview
:jbake-status: published
:keywords: Apache NetBeans wiki DevFaqDropdownMenuAddToolbarEnabled
:description: Apache NetBeans wiki DevFaqDropdownMenuAddToolbarEnabled
:toc: left
:toc-title:
:syntax: true
== How do I add a dropdown menu to toolbar that is selectively enabled/disabled?
Create an Action as described in link:DevFaqDropdownMenuAddToolbar.asciidoc[the general FAQ for to add a dropdown menu to a toolbar].
In this case, your action also needs to implement link:http://bits.netbeans.org/dev/javadoc/org-openide-util/org/openide/util/ContextAwareAction.html[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:
[source,java]
----
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:
[source,java]
----
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:
[source,java]
----
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:
[source,java]
----
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:
[source,java]
----
public void resultChanged(LookupEvent ev) {
setEnabled(!res.allItems().isEmpty());
}
----
A bit of bookkeeping is required in getToolbarPresenter() - at least until link:https://netbeans.org/bugzilla/show_bug.cgi?id=179814[issue 179814] is fixed, we will need to manually enable/disable the actions for our menu items:
[source,java]
----
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 link:http://article.gmane.org/gmane.comp.java.netbeans.modules.openide.devel/35436[see this post], posted in link:http://thread.gmane.org/gmane.comp.java.netbeans.modules.openide.devel/35424[on the old dev@openide NetBeans mailing lists].
=== Apache Migration Information
The content in this page was kindly donated by Oracle Corp. to the
Apache Software Foundation.
This page was exported from link:http://wiki.netbeans.org/DevFaqDropdownMenuAddToolbarEnabled[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-02-07, and needs to be reviewed.