Thanks to rabbit78 and fitzsim I figured out the problems discussed earlier on the list. This patch re-registers WHEN_IN_FOCUSED_WINDOW bindings when a JComponent is added to a Container because its top level container may have changed. The testcase from my last email now works even when the button is added to the frame after having it's bindings registered, and the modified test case is attached to this email.
Note there is still some inefficiency that I can work on. In both places that we update (addNotify and updateComponentInputMap) right now we just remove all bindings and then add them back (and in fact there may be some strange cases where this is incorrect ... I will have to do more in depth tests tomorrow), so there is work to be done here still. 2005-11-09 Anthony Balkissoon <[EMAIL PROTECTED]> * javax/swing/JComponent.java: (addNotify): Unregister all WHEN_IN_FOCUSED_WINDOW bindings for this JComponent and then register them with its (potentially) new top level ancestor. Removed unncessary code that copied regular (WHEN_FOCUSED) key bindings up the parent hierarchy. --Tony
Index: javax/swing/JComponent.java =================================================================== RCS file: /cvsroot/classpath/classpath/javax/swing/JComponent.java,v retrieving revision 1.80 diff -u -r1.80 JComponent.java --- javax/swing/JComponent.java 9 Nov 2005 21:59:40 -0000 1.80 +++ javax/swing/JComponent.java 9 Nov 2005 23:11:23 -0000 @@ -2828,41 +2828,22 @@ */ public void addNotify() { + // Register the WHEN_IN_FOCUSED_WINDOW keyboard bindings + // Note that here we unregister all bindings associated with + // this component and then re-register them. This may be more than + // necessary if the top-level ancestor hasn't changed. Should + // maybe improve this. + KeyboardManager km = KeyboardManager.getManager(); + km.clearBindingsForComp(this); + km.registerEntireMap((ComponentInputMap) + this.getInputMap(WHEN_IN_FOCUSED_WINDOW)); super.addNotify(); - // let parents inherit the keybord mapping - InputMap input = getInputMap(); - ActionMap actions = getActionMap(); - - Container parent = getParent(); - while ((parent != null) && (parent instanceof JComponent)) - { - JComponent jParent = (JComponent) parent; - InputMap parentInput = jParent.getInputMap(); - ActionMap parentAction = jParent.getActionMap(); - - KeyStroke[] ikeys = input.keys(); - for (int i = 0; i < ikeys.length; i++) - { - Object o = input.get(ikeys[i]); - parentInput.put(ikeys[i], o); - } - - Object[] akeys = actions.keys(); - for (int i = 0; i < akeys.length; i++) - { - Action a = actions.get(akeys[i]); - parentAction.put(akeys[i], a); - } - - parent = jParent.getParent(); - } - // Notify AncestorListeners. fireAncestorEvent(this, AncestorEvent.ANCESTOR_ADDED); // fire property change event for 'ancestor' - firePropertyChange("ancestor", null, parent); + firePropertyChange("ancestor", null, getParent()); } /**
import java.awt.*; import java.awt.event.*; import javax.swing.*; class Test { public static void main(String args[]) { // Set up the JFrame JFrame jf = new JFrame(); jf.setSize(200,200); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // A label and a button JCheckBox cb = new JCheckBox("dummy"); JButton b = new JButton(); // Actions for the button to perform Action focused = new AbstractAction(){ public void actionPerformed (ActionEvent e) { System.out.println ("I'm Focused"); } }; Action inWindow = new AbstractAction(){ public void actionPerformed (ActionEvent e) { System.out.println ("I'm In Focused Window"); } }; // Register the actions with the key 'a' KeyStroke k = KeyStroke.getKeyStroke('a'); b.registerKeyboardAction(focused, "focused", k, JComponent.WHEN_FOCUSED); b.registerKeyboardAction(inWindow, "window", k, JComponent.WHEN_IN_FOCUSED_WINDOW); // Add the components to the JFrame and show it jf.add(cb, BorderLayout.NORTH); jf.add(b, BorderLayout.SOUTH); jf.show(); } }
_______________________________________________ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches