You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by sd...@apache.org on 2023/01/06 13:10:58 UTC
[netbeans] branch master updated: Allow to collect contextual actions from layer path.
This is an automated email from the ASF dual-hosted git repository.
sdedic pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git
The following commit(s) were added to refs/heads/master by this push:
new 8d960aa926 Allow to collect contextual actions from layer path.
new 575e58c800 Merge pull request #5198 from sdedic/platform/action-forpath-lookup
8d960aa926 is described below
commit 8d960aa92632369280e96260937131d08d6ea36b
Author: Svata Dedic <sv...@oracle.com>
AuthorDate: Wed Jan 4 14:44:25 2023 +0100
Allow to collect contextual actions from layer path.
---
platform/openide.util.ui/apichanges.xml | 16 ++++++
platform/openide.util.ui/manifest.mf | 2 +-
.../src/org/openide/util/Utilities.java | 36 ++++++++++++
.../unit/src/org/openide/util/UtilitiesTest.java | 67 ++++++++++++++++++----
4 files changed, 110 insertions(+), 11 deletions(-)
diff --git a/platform/openide.util.ui/apichanges.xml b/platform/openide.util.ui/apichanges.xml
index c6c18b20d0..df05fa02de 100644
--- a/platform/openide.util.ui/apichanges.xml
+++ b/platform/openide.util.ui/apichanges.xml
@@ -27,6 +27,22 @@
<apidef name="actions">Actions API</apidef>
</apidefs>
<changes>
+ <change id="actionsForPathLookup">
+ <api name="util"/>
+ <summary>Added variant Utilities.actionsForPath with Lookup that produces context-aware actions</summary>
+ <version major="9" minor="28"/>
+ <date day="5" month="1" year="2023"/>
+ <author login="sdedic"/>
+ <compatibility addition="yes" binary="compatible" source="compatible" semantic="compatible" deprecation="no" deletion="no" modification="no"/>
+ <description>
+ <p>
+ Added a variant <a href="@TOP@/org/openide/util/Utilities.html#actionsForPath-java.lang.String-org.openide.util.Lookup-">actionsToPath</a> that instantiates context-bound actions if the registered action(s) implements
+ <a href="@TOP@/org/openide/util/ContextAwareAction.html">ContextAwareAction</a>.
+ Improves consistency with <a href="@TOP@/org/openide/util/Utilities.html#actionsToPopup-javax.swing.Action:A-org.openide.util.Lookup-">actionsToPopup</a> that supports contextual actions.
+ </p>
+ </description>
+ <class package="org.openide.util" name="Utilities"/>
+ </change>
<change id="findDialogParent">
<api name="util"/>
<summary>static method Utilities.findDialogParent added</summary>
diff --git a/platform/openide.util.ui/manifest.mf b/platform/openide.util.ui/manifest.mf
index 55ba833d87..b43b2faf9e 100644
--- a/platform/openide.util.ui/manifest.mf
+++ b/platform/openide.util.ui/manifest.mf
@@ -1,5 +1,5 @@
Manifest-Version: 1.0
OpenIDE-Module: org.openide.util.ui
OpenIDE-Module-Localizing-Bundle: org/openide/util/Bundle.properties
-OpenIDE-Module-Specification-Version: 9.27
+OpenIDE-Module-Specification-Version: 9.28
diff --git a/platform/openide.util.ui/src/org/openide/util/Utilities.java b/platform/openide.util.ui/src/org/openide/util/Utilities.java
index 3310e33657..ba5d85eb3e 100644
--- a/platform/openide.util.ui/src/org/openide/util/Utilities.java
+++ b/platform/openide.util.ui/src/org/openide/util/Utilities.java
@@ -1842,6 +1842,42 @@ public final class Utilities {
return actions;
}
+ /**
+ * Loads a menu sequence from a path, given a specific context as Lookup. This variant will allow to use action's contextual presence, enablement or selection,
+ * based on Lookup contents. If the registered action implements a {@link ContextAwareAction}, an instance bound to the passed `context' will be created - if
+ * the context factory returns {@code null}, indicating the action is not appropriate for the context, the registration will be skipped.
+ * Use {@link #actionsGlobalContext()} to supply global context.
+ *
+ * Any {@link Action} instances are returned as is;
+ * any {@link JSeparator} instances are translated to nulls.
+ * Warnings are logged for any other instances.
+ * @param path a path as given to {@link Lookups#forPath}, generally a layer folder name
+ * @param context the context passed to the action(s)
+ * @return a list of actions interspersed with null separators
+ * @since 7.14
+ */
+ public static List<? extends Action> actionsForPath(String path, Lookup context) {
+ List<Action> actions = new ArrayList<Action>();
+ for (Lookup.Item<Object> item : Lookups.forPath(path).lookupResult(Object.class).allItems()) {
+ if (Action.class.isAssignableFrom(item.getType())) {
+ Object instance = item.getInstance();
+ if (instance instanceof ContextAwareAction) {
+ Object contextAwareInstance = ((ContextAwareAction)instance).createContextAwareInstance(context);
+ if (contextAwareInstance == null) {
+ Logger.getLogger(Utilities.class.getName()).log(Level.WARNING,"ContextAwareAction.createContextAwareInstance(context) returns null. That is illegal!" + " action={0}, context={1}", new Object[] {instance, context});
+ } else {
+ instance = contextAwareInstance;
+ }
+ }
+ actions.add((Action) instance);
+ } else if (JSeparator.class.isAssignableFrom(item.getType())) {
+ actions.add(null);
+ } else {
+ Logger.getLogger(Utilities.class.getName()).log(Level.WARNING, "Unrecognized object of {0} found in actions path {1}", new Object[] {item.getType(), path});
+ }
+ }
+ return actions;
+ }
/**
* Global context for actions. Toolbar, menu or any other "global"
* action presenters shall operate in this context.
diff --git a/platform/openide.util.ui/test/unit/src/org/openide/util/UtilitiesTest.java b/platform/openide.util.ui/test/unit/src/org/openide/util/UtilitiesTest.java
index 9bada3d2d9..84bb0a930d 100644
--- a/platform/openide.util.ui/test/unit/src/org/openide/util/UtilitiesTest.java
+++ b/platform/openide.util.ui/test/unit/src/org/openide/util/UtilitiesTest.java
@@ -86,6 +86,7 @@ import java.awt.peer.ScrollbarPeer;
import java.awt.peer.TextAreaPeer;
import java.awt.peer.TextFieldPeer;
import java.awt.peer.WindowPeer;
+import java.beans.PropertyChangeListener;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
@@ -273,6 +274,39 @@ public class UtilitiesTest extends NbTestCase {
done.release();
}
}
+
+ public static class ContextData {
+ final String suffix;
+
+ public ContextData(String suffix) {
+ this.suffix = suffix;
+ }
+ }
+
+ public void testActionsForPathWithLookup() throws Exception {
+ MockLookup.setInstances(new NamedServicesProviderImpl());
+ // #156829: ensure that no tree lock is acquired.
+ final Semaphore ready = new Semaphore(0);
+ final Semaphore done = new Semaphore(0);
+ EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ synchronized (new JSeparator().getTreeLock()) {
+ ready.release();
+ try {
+ done.acquire();
+ } catch (InterruptedException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ }
+ }
+ });
+ ready.acquire();
+ try {
+ assertEquals("[hello-ehlo, null, there-ehlo]", Utilities.actionsForPath("stuff", Lookups.fixed(new ContextData("ehlo"))).toString());
+ } finally {
+ done.release();
+ }
+ }
private static class CustomToolkitComponent extends Component {
private Toolkit customToolkit;
@@ -511,21 +545,34 @@ public class UtilitiesTest extends NbTestCase {
return Lookup.EMPTY;
}
InstanceContent content = new InstanceContent();
- InstanceContent.Convertor<String, Action> actionConvertor = new InstanceContent.Convertor<String, Action>() {
- public Action convert(final String obj) {
- return new AbstractAction() {
+ class ContextAction extends AbstractAction implements ContextAwareAction {
+ final String obj;
- public void actionPerformed(ActionEvent e) {
- }
+ public ContextAction(String obj) {
+ this.obj = obj;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ }
- @Override
- public String toString() {
- return obj;
- }
- };
+ @Override
+ public String toString() {
+ return obj;
}
+ @Override
+ public Action createContextAwareInstance(Lookup actionContext) {
+ ContextData cd = actionContext.lookup(ContextData.class);
+ return new ContextAction(obj + (cd == null ? "-ctx" : "-" + cd.suffix));
+ }
+ }
+
+ InstanceContent.Convertor<String, Action> actionConvertor = new InstanceContent.Convertor<String, Action>() {
+ public Action convert(final String obj) {
+ return new ContextAction(obj);
+ }
+
public Class<? extends Action> type(String obj) {
return AbstractAction.class;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists