I corrected the installKeyboardActions() impl so that shared
input/action maps are used and installed correctly. Also, I implemented
the TreeHomeAction and fixed the TreeIncrementAction to work correctly.

2006-06-08  Roman Kennke  <[EMAIL PROTECTED]>

        * javax/swing/plaf/basic/BasicTreeUI.java
        (installKeyboardActions): Rewritten to correctly install the UI
        input and action maps.
        (getActionMap): New helper method.
        (createDefaultActionMap): New helper method.
        (TreeHomeAction.TreeHomeAction()): Implemented.
        (TreeHomeAction.actionPerformed): Implemented.
        (TreeHomeAction.isEnabled): Implemented.
        (TreeIncrementAction.TreeIncrementAction()): Implemented.
        (TreeIncrementAction.actionPerformed): Use action name as
command.
        (TreeIncrementAction.isEnabled): Implemented.

/Roman

Index: javax/swing/plaf/basic/BasicTreeUI.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicTreeUI.java,v
retrieving revision 1.141
diff -u -1 -0 -r1.141 BasicTreeUI.java
--- javax/swing/plaf/basic/BasicTreeUI.java	7 Jun 2006 20:46:03 -0000	1.141
+++ javax/swing/plaf/basic/BasicTreeUI.java	8 Jun 2006 12:38:11 -0000
@@ -73,37 +73,35 @@
 import javax.swing.AbstractAction;
 import javax.swing.Action;
 import javax.swing.ActionMap;
 import javax.swing.CellRendererPane;
 import javax.swing.Icon;
 import javax.swing.InputMap;
 import javax.swing.JComponent;
 import javax.swing.JScrollBar;
 import javax.swing.JScrollPane;
 import javax.swing.JTree;
-import javax.swing.KeyStroke;
 import javax.swing.LookAndFeel;
 import javax.swing.SwingUtilities;
 import javax.swing.Timer;
 import javax.swing.UIManager;
 import javax.swing.event.CellEditorListener;
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.MouseInputListener;
 import javax.swing.event.TreeExpansionEvent;
 import javax.swing.event.TreeExpansionListener;
 import javax.swing.event.TreeModelEvent;
 import javax.swing.event.TreeModelListener;
 import javax.swing.event.TreeSelectionEvent;
 import javax.swing.event.TreeSelectionListener;
 import javax.swing.plaf.ActionMapUIResource;
 import javax.swing.plaf.ComponentUI;
-import javax.swing.plaf.InputMapUIResource;
 import javax.swing.plaf.TreeUI;
 import javax.swing.tree.AbstractLayoutCache;
 import javax.swing.tree.DefaultTreeCellEditor;
 import javax.swing.tree.DefaultTreeCellRenderer;
 import javax.swing.tree.TreeCellEditor;
 import javax.swing.tree.TreeCellRenderer;
 import javax.swing.tree.TreeModel;
 import javax.swing.tree.TreeNode;
 import javax.swing.tree.TreePath;
 import javax.swing.tree.TreeSelectionModel;
@@ -1249,54 +1247,92 @@
     tree.setScrollsOnExpand(UIManager.getBoolean("Tree.scrollsOnExpand"));
     setExpandedIcon(UIManager.getIcon("Tree.expandedIcon"));
     setCollapsedIcon(UIManager.getIcon("Tree.collapsedIcon"));
   }
 
   /**
    * Install all keyboard actions for this
    */
   protected void installKeyboardActions()
   {
-    InputMap focusInputMap = (InputMap) UIManager.get("Tree.focusInputMap");
-    InputMapUIResource parentInputMap = new InputMapUIResource();
-    ActionMap parentActionMap = new ActionMapUIResource();
-    action = new TreeAction();
-    Object keys[] = focusInputMap.allKeys();
-
-    for (int i = 0; i < keys.length; i++)
-      {
-        parentInputMap.put(
-                           KeyStroke.getKeyStroke(
-                                                  ((KeyStroke) keys[i]).getKeyCode(),
-                                                  convertModifiers(((KeyStroke) keys[i]).getModifiers())),
-                           (String) focusInputMap.get((KeyStroke) keys[i]));
+    InputMap focusInputMap =
+      (InputMap) SharedUIDefaults.get("Tree.focusInputMap");
+    SwingUtilities.replaceUIInputMap(tree, JComponent.WHEN_FOCUSED,
+                                     focusInputMap);
+    InputMap ancestorInputMap =
+      (InputMap) SharedUIDefaults.get("Tree.ancestorInputMap");
+    SwingUtilities.replaceUIInputMap(tree,
+                                 JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
+                                 ancestorInputMap);
 
-        parentInputMap.put(
-                           KeyStroke.getKeyStroke(
-                                                  ((KeyStroke) keys[i]).getKeyCode(),
-                                                  ((KeyStroke) keys[i]).getModifiers()),
-                           (String) focusInputMap.get((KeyStroke) keys[i]));
+    action = new TreeAction();
 
-        parentActionMap.put(
-                            (String) focusInputMap.get((KeyStroke) keys[i]),
-                            new ActionListenerProxy(
-                                                    action,
-                                                    (String) focusInputMap.get((KeyStroke) keys[i])));
+    SwingUtilities.replaceUIActionMap(tree, getActionMap());
+  }
 
-      }
+  /**
+   * Creates and returns the shared action map for JTrees.
+   *
+   * @return the shared action map for JTrees
+   */
+  private ActionMap getActionMap()
+  {
+    ActionMap am = (ActionMap) UIManager.get("Tree.actionMap");
+    if (am == null)
+      {
+        am = createDefaultActions();
+        UIManager.getLookAndFeelDefaults().put("Tree.actionMap", am);
+      }
+    return am;
+  }
 
-    parentInputMap.setParent(tree.getInputMap(
-                                              JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).getParent());
-    parentActionMap.setParent(tree.getActionMap().getParent());
-    tree.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).setParent(
-                                                                              parentInputMap);
-    tree.getActionMap().setParent(parentActionMap);
+  /**
+   * Creates the default actions when there are none specified by the L&F.
+   *
+   * @return the default actions
+   */
+  private ActionMap createDefaultActions()
+  {
+    ActionMapUIResource am = new ActionMapUIResource();
+    Action action;
+
+    action= new TreeAction();
+    am.put(action.getValue(Action.NAME), action);
+
+    // TreeHomeAction.
+    action= new TreeHomeAction(-1, "selectFirst");
+    am.put(action.getValue(Action.NAME), action);
+    action= new TreeHomeAction(-1, "selectFirstChangeLead");
+    am.put(action.getValue(Action.NAME), action);
+    action= new TreeHomeAction(-1, "selectFirstExtendSelection");
+    am.put(action.getValue(Action.NAME), action);
+    action= new TreeHomeAction(1, "selectLast");
+    am.put(action.getValue(Action.NAME), action);
+    action= new TreeHomeAction(1, "selectLastChangeLead");
+    am.put(action.getValue(Action.NAME), action);
+    action= new TreeHomeAction(1, "selectLastExtendSelection");
+    am.put(action.getValue(Action.NAME), action);
+
+    // TreeIncrementAction.
+    action = new TreeIncrementAction(-1, "selectPrevious");
+    am.put(action.getValue(Action.NAME), action);
+    action = new TreeIncrementAction(-1, "selectPreviousExtendSelection");
+    am.put(action.getValue(Action.NAME), action);
+    action = new TreeIncrementAction(-1, "selectPreviousChangeLead");
+    am.put(action.getValue(Action.NAME), action);
+    action = new TreeIncrementAction(1, "selectNext");
+    am.put(action.getValue(Action.NAME), action);
+    action = new TreeIncrementAction(1, "selectNextExtendSelection");
+    am.put(action.getValue(Action.NAME), action);
+    action = new TreeIncrementAction(1, "selectNextChangeLead");
+    am.put(action.getValue(Action.NAME), action);
+    return am;
   }
 
   /**
    * Converts the modifiers.
    * 
    * @param mod - modifier to convert
    * @returns the new modifier
    */
   private int convertModifiers(int mod)
   {
@@ -2688,76 +2724,130 @@
    * or last cell to be visible based on direction.
    */
   public class TreeHomeAction
       extends AbstractAction
   {
 
     /** The direction, either home or end */
     protected int direction;
 
     /**
-     * Constructor
+     * Creates a new TreeHomeAction instance.
      * 
-     * @param direction - it is home or end
-     * @param name is the name of the direction
+     * @param dir the direction to go to, <code>-1</code> for home,
+     *        <code>1</code> for end
+     * @param name the name of the action
      */
-    public TreeHomeAction(int direction, String name)
-    throws NotImplementedException
+    public TreeHomeAction(int dir, String name)
     {
-      // TODO: Implement this properly
+      direction = dir;
+      putValue(Action.NAME, name);
     }
 
     /**
      * Invoked when an action occurs.
      * 
      * @param e is the event that occured
      */
     public void actionPerformed(ActionEvent e)
-    throws NotImplementedException
     {
-      // TODO: Implement this properly
+      if (tree != null)
+        {
+          String command = (String) getValue(Action.NAME);
+          if (command.equals("selectFirst"))
+            {
+              ensureRowsAreVisible(0, 0);
+              tree.setSelectionInterval(0, 0);
+            }
+          if (command.equals("selectFirstChangeLead"))
+            {
+              ensureRowsAreVisible(0, 0);
+              tree.setLeadSelectionPath(getPathForRow(tree, 0));
+            }
+          if (command.equals("selectFirstExtendSelection"))
+            {
+              ensureRowsAreVisible(0, 0);
+              TreePath anchorPath = tree.getAnchorSelectionPath();
+              if (anchorPath == null)
+                tree.setSelectionInterval(0, 0);
+              else
+                {
+                  int anchorRow = getRowForPath(tree, anchorPath);
+                  tree.setSelectionInterval(0, anchorRow);
+                  tree.setAnchorSelectionPath(anchorPath);
+                  tree.setLeadSelectionPath(getPathForRow(tree, 0));
+                }
+            }
+          else if (command.equals("selectLast"))
+            {
+              int end = getRowCount(tree) - 1;
+              ensureRowsAreVisible(end, end);
+              tree.setSelectionInterval(end, end);
+            }
+          else if (command.equals("selectLastChangeLead"))
+            {
+              int end = getRowCount(tree) - 1;
+              ensureRowsAreVisible(end, end);
+              tree.setLeadSelectionPath(getPathForRow(tree, end));
+            }
+          else if (command.equals("selectLastExtendSelection"))
+            {
+              int end = getRowCount(tree) - 1;
+              ensureRowsAreVisible(end, end);
+              TreePath anchorPath = tree.getAnchorSelectionPath();
+              if (anchorPath == null)
+                tree.setSelectionInterval(end, end);
+              else
+                {
+                  int anchorRow = getRowForPath(tree, anchorPath);
+                  tree.setSelectionInterval(end, anchorRow);
+                  tree.setAnchorSelectionPath(anchorPath);
+                  tree.setLeadSelectionPath(getPathForRow(tree, end));
+                }
+            }
+        }
     }
 
     /**
      * Returns true if the action is enabled.
      * 
      * @return true if the action is enabled.
      */
     public boolean isEnabled()
-    throws NotImplementedException
     {
-      // TODO: Implement this properly
-      return false;
+      return (tree != null) && tree.isEnabled();
     }
   }
 
   /**
    * TreeIncrementAction is used to handle up/down actions. Selection is moved
    * up or down based on direction.
    */
   public class TreeIncrementAction
-      extends AbstractAction
+    extends AbstractAction
   {
 
-    /** Specifies the direction to adjust the selection by. */
+    /**
+     * Specifies the direction to adjust the selection by.
+     */
     protected int direction;
 
     /**
-     * Constructor
+     * Creates a new TreeIncrementAction.
      * 
-     * @param direction up or down
+     * @param dir up or down, <code>-1</code> for up, <code>1</code> for down
      * @param name is the name of the direction
      */
-    public TreeIncrementAction(int direction, String name)
-    throws NotImplementedException
+    public TreeIncrementAction(int dir, String name)
     {
-      // TODO: Implement this properly
+      direction = dir;
+      putValue(Action.NAME, name);
     }
 
     /**
      * Invoked when an action occurs.
      * 
      * @param e is the event that occured
      */
     public void actionPerformed(ActionEvent e)
     {
       TreePath currentPath = tree.getLeadSelectionPath();
@@ -2768,21 +2858,21 @@
       else
         currentRow = 0;
 
       int rows = treeState.getRowCount();
 
       int nextRow = currentRow + 1;
       int prevRow = currentRow - 1;
       boolean hasNext = nextRow < rows;
       boolean hasPrev = prevRow >= 0 && rows > 0;
       TreePath newPath;
-      String command = e.getActionCommand();
+      String command = (String) getValue(Action.NAME);
 
       if (command.equals("selectPreviousChangeLead") && hasPrev)
         {
           newPath = treeState.getPathForRow(prevRow);
           tree.setSelectionPath(newPath);
           tree.setAnchorSelectionPath(newPath);
           tree.setLeadSelectionPath(newPath);
         }
       else if (command.equals("selectPreviousExtendSelection") && hasPrev)
         {
@@ -2831,24 +2921,22 @@
           tree.setLeadSelectionPath(newPath);
         }
     }
 
     /**
      * Returns true if the action is enabled.
      * 
      * @return true if the action is enabled.
      */
     public boolean isEnabled()
-    throws NotImplementedException
     {
-      // TODO: Implement this properly
-      return false;
+      return (tree != null) && tree.isEnabled();
     }
   }
 
   /**
    * Forwards all TreeModel events to the TreeState.
    */
   public class TreeModelHandler
       implements TreeModelListener
   {
     /**

Reply via email to