blob: fe8569621dd95d6c99b3dd095ada718c174e04ba [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.
//
= DevFaqActionNodePopupSubmenu
:jbake-type: wiki
:jbake-tags: wiki, devfaq, needsreview
:jbake-status: published
:keywords: Apache NetBeans wiki DevFaqActionNodePopupSubmenu
:description: Apache NetBeans wiki DevFaqActionNodePopupSubmenu
:toc: left
:toc-title:
:syntax: true
=== How do I make my Node have a submenu on its popup menu?
* Override `getActions()` of your Node subclass.
* Create a custom subclass of `javax.swing.Action` which implements the interface `Presenter.Popup`.
* Return a `JMenu` with whatever you want on it from `getPopupPresenter()`.
* Return that action in the array of actions from `getActions()`.
=== How do I make my Node have a submenu with context-sensitive action on its popup menu?
First here is the action for the submenu. The action is registered to the project context menu. It uses the `Presenter.Popup` interface to register itself as a submenu. In the `getPopupPresenter()` method the submenu is assembled via
`Utilities.actionsForPath`.
[source,java]
----
@ActionID(
category = "MyActions",
id = "de.markiewb.netbeans.sample.PopupAction"
)
@ActionRegistration(
displayName = "#CTL_PopupAction", lazy = false
)
@ActionReferences({
@ActionReference(path = "Projects/Actions")
})
@Messages("CTL_PopupAction=I am a submenu")
public final class PopupAction extends AbstractAction implements ActionListener, Presenter.Popup {
@Override
public void actionPerformed(ActionEvent e) {
//NOP
}
@Override
public JMenuItem getPopupPresenter() {
JMenu main = new JMenu(Bundle.CTL_PopupAction());
List<? extends Action> actionsForPath = Utilities.actionsForPath("Actions/MyActions/SubActions");
for (Action action : actionsForPath) {
main.add(action);
}
return main;
}
}
----
In the previous code snippet `Utilities.actionsForPath` has been used to resolve action(s) at `Actions/MyActions/SubActions`. Here is a context sensitive action, which is registered at this location.
[source,java]
----
@ActionID(
category = "MyActions/SubActions",
id = "de.markiewb.netbeans.sample.HelloProjectsAction"
)
@ActionRegistration(
displayName = "#CTL_HelloProjectsAction"
)
@Messages("CTL_HelloProjectsAction=HelloProjects...")
public final class HelloProjectsAction implements ActionListener {
private final List context;
public HelloProjectsAction(List context) {
this.context = context;
}
@Override
public void actionPerformed(ActionEvent ev) {
JOptionPane.showMessageDialog(null, context.size() + " projects selected: " + context);
}
}
----
See link:https://benkiew.wordpress.com/2015/09/01/nb-how-to-create-a-context-sensitive-action-within-a-submenu/[https://benkiew.wordpress.com/2015/09/01/nb-how-to-create-a-context-sensitive-action-within-a-submenu/]
=== How to create a context-aware submenu?
The requirement: "The submenu should be only enabled, when exactly two project nodes are selected. Only if this condition is true, the submenu items should be displayed."
See the following sample code. The most important part of the popup action is to emulate a context-aware action using a lookup listener.
[source,java]
----
@ActionID(
category = "MyActions",
id = "de.markiewb.netbeans.sample.ContextAwarePopupAction"
)
@ActionRegistration(
displayName = "#CTL_ContextAwarePopupAction", lazy = false
)
@ActionReferences({
@ActionReference(path = "Projects/Actions")
})
@Messages("CTL_ContextAwarePopupAction=I am a context-aware submenu")
public final class ContextAwarePopupAction extends AbstractAction implements ActionListener, Presenter.Popup {
private final Lookup.Result<Project> result;
private final transient LookupListener lookupListener;
public ContextAwarePopupAction() {
putValue(NAME, Bundle.CTL_ContextAwarePopupAction());
//disabled by default - at loading time
setEnabled(false);
//create an action, which is only enabled when exactly 2 projects are selected
result = Utilities.actionsGlobalContext().lookupResult(Project.class);
this.lookupListener = new LookupListener() {
@Override
public void resultChanged(LookupEvent ev) {
final Runnable runnable = new Runnable() {
@Override
public void run() {
int s = result.allInstances().size();
ContextAwarePopupAction.this.setEnabled(s == 2);
}
};
// to make sure that it will be executed on EDT
if (EventQueue.isDispatchThread()) {
runnable.run();
} else {
SwingUtilities.invokeLater(runnable);
}
}
};
result.addLookupListener(WeakListeners.create(LookupListener.class, this.lookupListener, result));
}
@Override
public void actionPerformed(ActionEvent e) {
//NOP
}
@Override
public JMenuItem getPopupPresenter() {
JMenu main = new JMenu(this);
List<? extends Action> actionsForPath = Utilities.actionsForPath("Actions/MyActions/SubActions");
for (Action action : actionsForPath) {
main.add(action);
}
return main;
}
}
----
See link:https://benkiew.wordpress.com/2015/09/13/nb-how-to-create-a-context-aware-submenu/[https://benkiew.wordpress.com/2015/09/13/nb-how-to-create-a-context-aware-submenu/]
=== 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/DevFaqActionNodePopupSubmenu[http://wiki.netbeans.org/DevFaqActionNodePopupSubmenu] ,
that was last modified by NetBeans user Markiewb
on 2015-09-13T19:53:44Z.
*NOTE:* This document was automatically converted to the AsciiDoc format on 2018-02-07, and needs to be reviewed.