Window-level proxy actions

  4 posts   Feedicon  
Replies: 3 - Last Post: April 27, 2011 13:59
by: jekkos
showing 1 - 4 of 4
 
Posted: October 19, 2010 19:12 by jamiehope
Hello, I'm new to BSAF so my apologies if this is not the correct forum or list.

I have been experimenting with proxy actions and have encountered what I perceive to be a limitation: they can only defer to Actions of the particular JComponent with keyboard focus, and not to any other components up the layout hierarchy -- in particular, the containing window's JRootPane.

I have written a WindowActions class (modeled after TextActions) which provides close/minimize/zoom actions and can install them in the action map of the JRootPane of a JFrame (and, in principle, a JDialog or JWindow). In my Application subclass, I follow the TextActions model and add a PCL to the keyboard focus manager which listens for "activeWindow" changes and calls WindowActions.updateActiveWindow() (which does the analog of TextActions.updateFocusOwner).

In order for my
@ProxyActions("close", "minimize", "zoom")
to get connected to the window actions, and for them to work on JFrames containing a java.awt.Canvas with keyboard focus, I had to make these changes to ActionManager:

Index: src/main/java/org/jdesktop/application/ActionManager.java
===================================================================
--- src/main/java/org/jdesktop/application/ActionManager.java	(revision 178)
+++ src/main/java/org/jdesktop/application/ActionManager.java	(working copy)
@@ -5,6 +5,7 @@
  */
 package org.jdesktop.application;
 
+import java.awt.Component;
 import java.awt.KeyboardFocusManager;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
@@ -193,7 +194,8 @@
             if ("permanentFocusOwner".equals(e.getPropertyName())) {
                 JComponent oldOwner = getContext().getFocusOwner();
                 Object newValue = e.getNewValue();
-                JComponent newOwner = (newValue instanceof JComponent) ? (JComponent) newValue : null;
+                // Find the nearest JComponent in the layout hierarchy.
+                JComponent newOwner = getJComponent((Component)newValue);
                 textActions.updateFocusOwner(oldOwner, newOwner);
                 getContext().setFocusOwner(newOwner);
                 updateAllProxyActions(oldOwner, newOwner);
@@ -237,8 +239,29 @@
             } else {
                 proxyAction.setProxy(null);
                 proxyAction.setProxySource(null);
+                // Now see if any JComponent upstream has this Action.
+                JComponent ancestor = focusOwner;
+                while ((ancestor = getJComponent(ancestor.getParent())) != null) {
+                    ActionMap ancestorAM = ancestor.getActionMap();
+                    proxy = ancestorAM.get(proxyActionName);
+                    if (proxy != null) {
+                        proxyAction.setProxy(proxy);
+                        proxyAction.setProxySource(ancestor);
+                        break;
+                    }
+                }
             }
         }
     }
+
+    /* Find the first JComponent in the layout hierarchy starting at
+     * the given Component and working up toward the top level
+     * ancestor.
+     */
+    private JComponent getJComponent(Component c) {
+        if (c == null) return null;
+        if (c instanceof JComponent) return (JComponent) c;
+        return getJComponent(c.getParent());
+    }
 }
 


This works for me, but I realize that some Actions really should be bound only to the JComponent (if any) with focus without falling through to parent components. To determine which behavior to follow would require a new parameter, but I don't have a good feel for whether it should be intrinsic to the @ProxyAction or the @Action.
 
Posted: April 27, 2011 11:56 by jekkos
Dear Jamie,

I am quite interested in your patch, as I currently want to implement something similar.
could you possibly share the code for the WindowsActions class, too?

thanks.
 
Posted: April 27, 2011 13:25 by etf
Do we have a jira ticket for this? Please attache all code snippets to it.
 
Posted: April 27, 2011 13:59 by jekkos
Not yet, maybe somebody can create one? I don't know if jamie is still active here, as the post was made some time ago.
Replies: 3 - Last Post: April 27, 2011 13:59
by: jekkos
  • Mysql
  • Glassfish
  • Jruby
  • Rails
  • Nblogo
Terms of Use; Privacy Policy;
© 2010, Oracle Corporation and/or its affiliates
(revision 20120518.3c65429)
 
 
Close
loading
Please Confirm
Close