jamiehope
|
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")
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. |
Window-level proxy actions
Replies: 3 - Last Post: April 27, 2011 13:59
by: jekkos
by: jekkos
showing 1 - 4 of 4
Replies: 3 - Last Post: April 27, 2011 13:59
by: jekkos
by: jekkos







