[cp-patches] FYI: JSplitPane keyboard bindings

David Gilbert david.gilbert at object-refinery.com
Tue Jun 6 15:17:11 UTC 2006


This patch (committed) puts in place the keyboard bindings for the JSplitPane class:

2006-06-06  David Gilbert  <david.gilbert at object-refinery.com>

	* javax/swing/JSplitPane.java
	(AccessibleJSplitPane): API doc fixes,
	(setDividerLocation): Likewise,
	* javax/swing/plaf/basic/BasicLookAndFeel.java
	(initComponentDefaults): Additions to SplitPane.ancestorInputMap,
	* javax/swing/plaf/basic/BasicSplitPaneUI.java
	(getInputMap): New method,
	(getActionMap): New method,
	(createActionMap): New method,
	(installKeyboardActions): Implemented,
	(uninstallKeyboardActions): Implemented.

The essentials work, but there is still some more to do on the focus toggling (and 
also highlighting the divider when keyboard movement is enabled).  Also the maximum 
position for the divider isn't calculated correctly...I'll look at this some more 
tonight.

Regards,

Dave
-------------- next part --------------
Index: javax/swing/JSplitPane.java
===================================================================
RCS file: /sources/classpath/classpath/javax/swing/JSplitPane.java,v
retrieving revision 1.17
diff -u -r1.17 JSplitPane.java
--- javax/swing/JSplitPane.java	3 May 2006 18:04:12 -0000	1.17
+++ javax/swing/JSplitPane.java	6 Jun 2006 14:51:59 -0000
@@ -108,7 +108,7 @@
 
     /**
      * Returns an object that provides access to the current, minimum and 
-     * maximum values for the {@link JSlider}.  Since this class implements 
+     * maximum values for the {@link JSplitPane}.  Since this class implements 
      * {@link AccessibleValue}, it returns itself.
      *
      * @return The accessible value.
@@ -136,9 +136,9 @@
      * listeners.  If the supplied value is <code>null</code>, this method 
      * does nothing and returns <code>false</code>.
      *
-     * @param value  the new slider value (<code>null</code> permitted).
+     * @param value  the new divider location (<code>null</code> permitted).
      *
-     * @return <code>true</code> if the slider value is updated, and 
+     * @return <code>true</code> if the divider location value is updated, and 
      *     <code>false</code> otherwise.
      */
     public boolean setCurrentAccessibleValue(Number value)
@@ -699,7 +699,8 @@
    * @param proportionalLocation A double that describes the location of the
    *        divider.
    *
-   * @throws IllegalArgumentException DOCUMENT ME!
+   * @throws IllegalArgumentException if <code>proportionalLocation</code> is
+   *     not in the range from 0.0 to 1.0 inclusive.
    */
   public void setDividerLocation(double proportionalLocation)
   {
Index: javax/swing/plaf/basic/BasicLookAndFeel.java
===================================================================
RCS file: /sources/classpath/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java,v
retrieving revision 1.90
diff -u -r1.90 BasicLookAndFeel.java
--- javax/swing/plaf/basic/BasicLookAndFeel.java	10 Apr 2006 21:06:55 -0000	1.90
+++ javax/swing/plaf/basic/BasicLookAndFeel.java	6 Jun 2006 14:52:02 -0000
@@ -1,5 +1,5 @@
 /* BasicLookAndFeel.java --
-   Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -1147,14 +1147,16 @@
         "F8",  "startResize",
         "END",  "selectMax",
         "HOME",  "selectMin",
-        "LEFT",  "negativeIncremnent",
+        "LEFT",  "negativeIncrement",
         "KP_UP", "negativeIncrement",
         "KP_DOWN", "positiveIncrement",
         "UP",  "negativeIncrement",
         "RIGHT", "positiveIncrement",
         "KP_LEFT", "negativeIncrement",
         "DOWN",  "positiveIncrement",
-        "KP_RIGHT", "positiveIncrement"
+        "KP_RIGHT", "positiveIncrement",
+        "shift ctrl pressed TAB", "focusOutBackward",
+        "ctrl pressed TAB", "focusOutForward"
       }),
       "SplitPane.background", new ColorUIResource(light),
       "SplitPane.border", new BasicBorders.SplitPaneBorder(null, null),
Index: javax/swing/plaf/basic/BasicSplitPaneUI.java
===================================================================
RCS file: /sources/classpath/classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java,v
retrieving revision 1.28
diff -u -r1.28 BasicSplitPaneUI.java
--- javax/swing/plaf/basic/BasicSplitPaneUI.java	17 Apr 2006 07:41:05 -0000	1.28
+++ javax/swing/plaf/basic/BasicSplitPaneUI.java	6 Jun 2006 14:52:04 -0000
@@ -1,5 +1,5 @@
 /* BasicSplitPaneUI.java --
-   Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006, Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -38,8 +38,6 @@
 
 package javax.swing.plaf.basic;
 
-import gnu.classpath.NotImplementedException;
-
 import java.awt.Canvas;
 import java.awt.Color;
 import java.awt.Component;
@@ -57,11 +55,17 @@
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 
+import javax.swing.AbstractAction;
+import javax.swing.ActionMap;
+import javax.swing.InputMap;
 import javax.swing.JComponent;
+import javax.swing.JSlider;
 import javax.swing.JSplitPane;
 import javax.swing.KeyStroke;
 import javax.swing.LookAndFeel;
+import javax.swing.SwingUtilities;
 import javax.swing.UIManager;
+import javax.swing.plaf.ActionMapUIResource;
 import javax.swing.plaf.ComponentUI;
 import javax.swing.plaf.SplitPaneUI;
 import javax.swing.plaf.UIResource;
@@ -1046,21 +1050,143 @@
   }
 
   /**
-   * This method installs the keyboard actions for the JSplitPane.
+   * Returns the input map for the specified condition.
+   * 
+   * @param condition  the condition.
+   * 
+   * @return The input map.
+   */
+  InputMap getInputMap(int condition) 
+  {
+    if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
+      return (InputMap) UIManager.get("SplitPane.ancestorInputMap");
+    return null;
+  }
+
+  /**
+   * Returns the action map for the {@link JSplitPane}.  All sliders share
+   * a single action map which is created the first time this method is 
+   * called, then stored in the UIDefaults table for subsequent access.
+   * 
+   * @return The shared action map.
+   */
+  ActionMap getActionMap() 
+  {
+    ActionMap map = (ActionMap) UIManager.get("SplitPane.actionMap");
+
+    if (map == null) // first time here
+      {
+        map = createActionMap();
+        if (map != null)
+          UIManager.put("SplitPane.actionMap", map);
+      }
+    return map;
+  }
+
+  /**
+   * Creates the action map shared by all {@link JSlider} instances.
+   * This method is called once by {@link #getActionMap()} when it 
+   * finds no action map in the UIDefaults table...after the map is 
+   * created, it gets added to the defaults table so that subsequent 
+   * calls to {@link #getActionMap()} will return the same shared 
+   * instance.
+   * 
+   * @return The action map.
+   */
+  ActionMap createActionMap()
+  {
+    ActionMap map = new ActionMapUIResource();
+    map.put("toggleFocus", 
+            new AbstractAction("toggleFocus") {
+              public void actionPerformed(ActionEvent event)
+              {
+                // FIXME: What to do here?
+              }
+            }
+    );
+    map.put("startResize", 
+            new AbstractAction("startResize") {
+              public void actionPerformed(ActionEvent event)
+              {
+                splitPane.requestFocus();
+              }
+            }
+    );
+    map.put("selectMax", 
+            new AbstractAction("selectMax") {
+              public void actionPerformed(ActionEvent event)
+              {
+                splitPane.setDividerLocation(1.0);
+              }
+            }
+    );
+    map.put("selectMin", 
+            new AbstractAction("selectMin") {
+              public void actionPerformed(ActionEvent event)
+              {
+                splitPane.setDividerLocation(0.0);
+              }
+            }
+    );
+    map.put("negativeIncrement", 
+            new AbstractAction("negativeIncrement") {
+              public void actionPerformed(ActionEvent event)
+              {
+                setDividerLocation(splitPane, Math.max(dividerLocation 
+                    - KEYBOARD_DIVIDER_MOVE_OFFSET, 0));
+              }
+            }
+    );
+    map.put("positiveIncrement", 
+            new AbstractAction("positiveIncrement") {
+              public void actionPerformed(ActionEvent event)
+              {
+                setDividerLocation(splitPane, dividerLocation 
+                    + KEYBOARD_DIVIDER_MOVE_OFFSET);
+              }
+            }
+    );
+    map.put("focusOutBackward",
+            new AbstractAction("focusOutBackward") {
+              public void actionPerformed(ActionEvent event)
+              {
+                // FIXME: implement this
+              }
+            }
+    );    
+    map.put("focusOutForward",
+            new AbstractAction("focusOutForward") {
+              public void actionPerformed(ActionEvent event)
+              {
+                // FIXME: implement this
+              }
+            }
+    );    
+    return map;
+  }
+
+  /**
+   * Installs any keyboard actions. The list of keys that need to be bound are
+   * listed in Basic look and feel's defaults.
    */
   protected void installKeyboardActions()
-    throws NotImplementedException
   {
-    // FIXME: implement.
+    InputMap keyMap = getInputMap(
+        JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
+    SwingUtilities.replaceUIInputMap(splitPane, 
+        JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, keyMap);
+    ActionMap map = getActionMap();
+    SwingUtilities.replaceUIActionMap(splitPane, map);
   }
 
   /**
    * This method reverses the work done in installKeyboardActions.
    */
   protected void uninstallKeyboardActions()
-    throws NotImplementedException
   {
-    // FIXME: implement.
+    SwingUtilities.replaceUIActionMap(splitPane, null);
+    SwingUtilities.replaceUIInputMap(splitPane, 
+        JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null);
   }
 
   /**


More information about the Classpath-patches mailing list