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

Reply via email to