Fixed up BasicTreeUI because it was not efficent when painting.

2005-10-05  Lillian Angel  <[EMAIL PROTECTED]>

        * javax/swing/plaf/metal/MetalTreeUI.java
        (installUI): Fixed to call toggleExpandState instead.
        * javax/swing/plaf/basic/BasicTreeUI.java
        (getPathForRow): Used currentVisiblePath to get Path.
        (getRowForPath): Used currentVisiblePath to get row.
        (getRowCount): Returned currentVisiblePath length.
        (updateLayoutCacheExpandedNodes): Took out unneeded code.
        (installUI): Fixed to call toggleExpandState instead.
        (getPreferredSize): Made more efficent by using 
        currentVisiblePath.
        (toggleExpandState): Called updateCurrentVisiblePath.
        (getCellLocation): Made more efficent.
        (paintNode): Removed.
        (paintRecursive): Made more efficent, changed paintNode calls to
        paintRow.
        (getNextVisibleNode): Reimplemented to use currentVisiblePath.
        (getPreviousVisibleNode): Likewise.
        (paintRow): Implemented.
        (updateCurrentVisiblePath): New helper used to cache the current
        visible path.

Index: javax/swing/plaf/basic/BasicTreeUI.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicTreeUI.java,v
retrieving revision 1.84
diff -u -r1.84 BasicTreeUI.java
--- javax/swing/plaf/basic/BasicTreeUI.java	29 Sep 2005 22:51:34 -0000	1.84
+++ javax/swing/plaf/basic/BasicTreeUI.java	5 Oct 2005 21:18:46 -0000
@@ -242,6 +242,9 @@
   
   /** The bounds of the current cell. */
   Rectangle bounds;
+  
+  /** The current path of the visible nodes in the tree. */
+  TreePath currentVisiblePath;
 
   /** Listeners */
   private PropertyChangeListener propertyChangeListener;
@@ -648,18 +651,9 @@
   {
     if (treeModel != null)
       {
-        Object node = treeModel.getRoot();
-        if (!tree.isRootVisible()
-            && tree.isExpanded(new TreePath(getPathToRoot(node, 0))))
-          node = getNextNode(node);
-
-        for (int i = 0; i < row; i++)
-          node = getNextVisibleNode(node);
-
-        if (node == null)
-          return null;
-
-        return new TreePath(getPathToRoot(node, 0));
+        Object[] nodes = currentVisiblePath.getPath();
+        if (row < nodes.length)
+          return new TreePath(getPathToRoot(nodes[row], 0));
       }
     return null;
   }
@@ -680,13 +674,16 @@
   {
     int row = 0;
     Object dest = path.getLastPathComponent();
-    Object curr = treeModel.getRoot();
-    while (curr != null && !curr.equals(dest))
-      {
-        ++row;
-        curr = getNextVisibleNode(curr);
+    int rowCount = getRowCount(tree);
+    Object[] nodes = currentVisiblePath.getPath();
+    while (row < rowCount)
+      {
+        if (dest.equals(nodes[row]))
+          return row;
+        row++;          
       }
-    return row;
+      
+    return -1;
   }
 
   /**
@@ -698,21 +695,7 @@
    */
   public int getRowCount(JTree tree)
   {
-    int count = 0;
-    if (treeModel != null)
-      {
-        Object node = treeModel.getRoot();
-        if (!tree.isRootVisible()
-            && tree.isExpanded(new TreePath((getPathToRoot(node, 0)))))
-          node = getNextNode(node);
-
-        while (node != null)
-          {
-            count++;
-            node = getNextVisibleNode(node);
-          }
-      }
-    return count;
+    return currentVisiblePath.getPathCount();
   }
 
   /**
@@ -1087,8 +1070,7 @@
   protected void updateLayoutCacheExpandedNodes()
   {
     if (treeModel != null)
-      updateExpandedDescendants(new TreePath(getPathToRoot(treeModel.
-                                                           getRoot(), 0)));
+      updateExpandedDescendants(new TreePath(treeModel.getRoot()));
   }
 
   /**
@@ -1340,7 +1322,11 @@
     TreeModel mod = tree.getModel();
     setModel(mod);
     if (mod != null)
-      tree.expandPath(new TreePath(mod.getRoot()));
+      {
+        TreePath path = new TreePath(mod.getRoot());
+        if (!tree.isExpanded(path))
+          toggleExpandState(path);
+      }
     treeSelectionModel = tree.getSelectionModel();
 
     installKeyboardActions();
@@ -1482,25 +1466,11 @@
   {
     // FIXME: checkConsistancy not implemented, c not used
     int maxWidth = 0;
-    int count = 0;
-    if (treeModel != null)
-      {
-        Object node = treeModel.getRoot();
-        if (node != null)
-          {
-            maxWidth = (int) (getCellBounds(0, 0, node).getWidth());
-            while (node != null)
-              {
-                count++;
-                Object nextNode = getNextVisibleNode(node);
-                if (nextNode != null)
-                  maxWidth = Math.max(maxWidth,
-                                      (int) (getCellBounds(0, 0, nextNode).getWidth()));
-                node = nextNode;
-              }
-          }
-      }
-    return new Dimension(maxWidth, (getRowHeight() * count));
+    Object[] path = currentVisiblePath.getPath();
+    for (int i = 0; i < path.length; i++)
+      maxWidth = Math.max(maxWidth,
+                          (int) (getCellBounds(0, 0, path[i]).getWidth()));
+    return new Dimension(maxWidth, (getRowHeight() * path.length));
   }
 
   /**
@@ -3028,80 +2996,19 @@
     int rowHeight = getRowHeight();
     if (startNode == null || startNode.equals(node))
       {
-        if (!tree.isRootVisible()
-            && tree.isExpanded(new TreePath(mod.getRoot())))
-          return new Point(x + ((getLevel(node)) * rightChildIndent), y);
-
-        return new Point(x + ((getLevel(node) + 1) * rightChildIndent), y);
+        int level = getLevel(node);
+        if (level == 0)
+          return new Point(x, y);
+        if (!tree.isRootVisible() && 
+            tree.isExpanded(new TreePath(mod.getRoot())))
+          return new Point(x + ((level - 1) * rightChildIndent), y);
+        return new Point(x + (level * rightChildIndent), y);
       }
-
-    if (!mod.isLeaf(startNode)
-        && tree.isExpanded(new TreePath(getPathToRoot(startNode, 0)))
-        && !mod.isLeaf(startNode) && mod.getChildCount(startNode) > 0)
-      {
-        Object child = mod.getChild(startNode, 0);
-        if (child != null)
-          return getCellLocation(x, y + rowHeight, tree, mod, node, child);
-      }
-
     return getCellLocation(x, y + rowHeight, tree, mod, node,
                            getNextVisibleNode(startNode));
   }
 
   /**
-   * Paints a node in the tree Package private for use in inner classes.
-   * 
-   * @param g
-   *          the Graphics context in which to paint
-   * @param x
-   *          the x location of the node
-   * @param y
-   *          the y location of the node
-   * @param tree
-   *          the tree to draw on
-   * @param node
-   *          the object to draw
-   */
-  void paintNode(Graphics g, int x, int y, JTree tree, Object node,
-                 boolean isLeaf)
-  {
-    TreePath curr = new TreePath(getPathToRoot(node, 0));
-    boolean selected = tree.isPathSelected(curr);
-    boolean expanded = false;
-    boolean hasIcons = false;
-
-    if (tree.isVisible(curr))
-      {
-        if (!isLeaf)
-          expanded = tree.isExpanded(curr);
-
-        if (editingComponent != null && editingPath != null && isEditing(tree)
-            && node.equals(editingPath.getLastPathComponent()))
-          {
-            Rectangle bounds = getPathBounds(tree, editingPath);
-            rendererPane.paintComponent(g, editingComponent.getParent(), null,
-                                        new Rectangle(0, 0, bounds.width,
-                                                      bounds.height));
-          }
-        else
-          {
-            TreeCellRenderer dtcr = tree.getCellRenderer();
-            if (dtcr == null)
-              dtcr = createDefaultCellRenderer();
-
-            int row = getRowForPath(tree, curr);
-
-            Component c = dtcr.getTreeCellRendererComponent(tree, node,
-                                                            selected, expanded,
-                                                            isLeaf, row, false);
-
-            rendererPane.paintComponent(g, c, c.getParent(),
-                                        getCellBounds(x, y, node));
-          }
-      }
-  }
-
-  /**
    * Recursively paints all elements of the tree Package private for use in
    * inner classes.
    * 
@@ -3111,8 +3018,6 @@
    *          of the current object
    * @param descent
    *          is the number of elements drawn
-   * @param childNumber
-   *          is the index of the current child in the tree
    * @param depth
    *          is the depth of the current object in the tree
    * @param tree
@@ -3123,7 +3028,7 @@
    *          is the current object to draw
    * @return int - current descent of the tree
    */
-  int paintRecursive(Graphics g, int indentation, int descent, int childNumber,
+  int paintRecursive(Graphics g, int indentation, int descent,
                      int depth, JTree tree, TreeModel mod, Object curr)
   {
     Rectangle clip = tree.getVisibleRect();
@@ -3131,38 +3036,42 @@
         || descent > clip.y + clip.height + getRowHeight())
       return descent;
 
+    TreePath path = new TreePath(getPathToRoot(curr, 0));
     int halfHeight = getRowHeight() / 2;
     int halfWidth = rightChildIndent / 2;
     int y0 = descent + halfHeight;
     int heightOfLine = descent + halfHeight;
+    int row = getRowForPath(tree, path);
     boolean isRootVisible = tree.isRootVisible();
-
-    if (mod.isLeaf(curr))
+    boolean isExpanded = tree.isExpanded(path);
+    boolean isLeaf = mod.isLeaf(curr);
+    Rectangle bounds = getPathBounds(tree, path);
+    Object root = mod.getRoot();
+    
+    if (isLeaf)
       {
-        paintNode(g, indentation + 4, descent, tree, curr, true);
+        paintRow(g, clip, null, bounds, path, row, true, false, true);
         descent += getRowHeight();
       }
     else
-      {
+      {        
         if (depth > 0 || isRootVisible)
           {
-            paintNode(g, indentation + 4, descent, tree, curr, false);
+            paintRow(g, clip, null, bounds, path, row, isExpanded, false, false);
             descent += getRowHeight();
             y0 += halfHeight;
           }
-
-        int max = 0;
-        if (!mod.isLeaf(curr))
-          max = mod.getChildCount(curr);
-        if (tree.isExpanded(new TreePath(getPathToRoot(curr, 0))))
+        
+        int max = mod.getChildCount(curr);
+        if (isExpanded)
           {
             for (int i = 0; i < max; i++)
               {
                 int indent = indentation + rightChildIndent;
                 if (!isRootVisible && depth == 0)
                   indent = 0;
-                else if ((!isRootVisible && !curr.equals(mod.getRoot()))
-                         || isRootVisible)
+                else if (isRootVisible || 
+                    (!isRootVisible && !curr.equals(root)))
                   {
                     g.setColor(getHashColor());
                     heightOfLine = descent + halfHeight;
@@ -3170,14 +3079,14 @@
                       indentation + halfWidth, indentation + rightChildIndent);
                   }
 
-                descent = paintRecursive(g, indent, descent, i, depth + 1,
+                descent = paintRecursive(g, indent, descent, depth + 1,
                                          tree, mod, mod.getChild(curr, i));
               }
           }
       }
 
-    if (tree.isExpanded(new TreePath(getPathToRoot(curr, 0))))
-      if (y0 != heightOfLine && !mod.isLeaf(curr)
+    if (isExpanded)
+      if (y0 != heightOfLine && !isLeaf
           && mod.getChildCount(curr) > 0)
         {
           g.setColor(getHashColor());
@@ -3329,40 +3236,6 @@
   }
 
   /**
-   * Get next visible node in the tree. Package private for use in inner
-   * classes.
-   * 
-   * @param the
-   *          current node
-   * @return the next visible node in the JTree. Return null if there are no
-   *         more.
-   */
-  Object getNextVisibleNode(Object node)
-  {
-    Object next = null;
-    TreePath current = null;
-
-    if (node != null)
-      next = getNextNode(node);
-
-    if (next != null)
-      {
-        current = new TreePath(getPathToRoot(next, 0));
-        if (tree.isVisible(current))
-          return next;
-
-        while (next != null && !tree.isVisible(current))
-          {
-            next = getNextNode(next);
-
-            if (next != null)
-              current = new TreePath(getPathToRoot(next, 0));
-          }
-      }
-    return next;
-  }
-
-  /**
    * Get previous visible node in the tree. Package private for use in inner
    * classes.
    * 
@@ -3373,27 +3246,14 @@
    */
   Object getPreviousVisibleNode(Object node)
   {
-    Object prev = null;
-    TreePath current = null;
-
-    if (node != null)
-      prev = getPreviousNode(node);
-
-    if (prev != null)
-      {
-        current = new TreePath(getPathToRoot(prev, 0));
-        if (tree.isVisible(current))
-          return prev;
-
-        while (prev != null && !tree.isVisible(current))
-          {
-            prev = getPreviousNode(prev);
-
-            if (prev != null)
-              current = new TreePath(getPathToRoot(prev, 0));
-          }
-      }
-    return prev;
+    Object[] nodes = currentVisiblePath.getPath();
+    int i = 0;
+    while (i < nodes.length && !node.equals(nodes[i]))
+      i++;
+    // return the next node
+    if (i-1 > 0)
+      return nodes[i-1];
+    return null;
   }
 
   /**
@@ -3425,7 +3285,7 @@
    * Returns the previous node in the tree Package private for use in inner
    * classes.
    * 
-   * @param the
+   * @param node
    *          current node
    * @return the previous node in the tree
    */
@@ -3760,7 +3620,32 @@
                           boolean isExpanded, boolean hasBeenExpanded,
                           boolean isLeaf)
   {
-    // FIXME: not implemented.
+    boolean selected = tree.isPathSelected(path);
+    boolean hasIcons = false;
+    Object node = path.getLastPathComponent();
+
+    if (tree.isVisible(path))
+      {
+        if (editingComponent != null && editingPath != null && isEditing(tree)
+            && node.equals(editingPath.getLastPathComponent()))
+          {
+            rendererPane.paintComponent(g, editingComponent.getParent(), null,
+                                        new Rectangle(0, 0, bounds.width, bounds.height));
+          }
+        else
+          {
+            TreeCellRenderer dtcr = tree.getCellRenderer();
+            if (dtcr == null)
+              dtcr = createDefaultCellRenderer();
+
+            Component c = dtcr.getTreeCellRendererComponent(tree, node,
+                                                            selected, isExpanded,
+                                                            isLeaf, row, false);
+            // add padding between line and node
+            bounds.x += 4;
+            rendererPane.paintComponent(g, c, c.getParent(), bounds);
+          }
+      }
   }
 
   /**
@@ -3787,5 +3672,52 @@
   {
     // FIXME: not implemented.
     return false;
+  }
+  
+  /**
+   * Updates the cached current TreePath of all visible
+   * nodes in the tree.
+   */
+  void updateCurrentVisiblePath()
+  {
+    Object next = treeModel.getRoot();
+    if (!isRootVisible() && tree.isExpanded(new TreePath(next)))
+      next = getNextNode(next);
+    TreePath current = null;
+
+    while (next != null)
+      {
+        if (current != null)
+          current = current.pathByAddingChild(next);
+        else
+          current = new TreePath(next);
+
+        do
+          next = getNextNode(next);
+        while (next != null
+               && !tree.isVisible(new TreePath(getPathToRoot(next, 0))));
+      }
+    currentVisiblePath = current;
+  }
+  
+  /**
+   * Get next visible node in the currentVisiblePath. Package private for use in
+   * inner classes.
+   * 
+   * @param node
+   *          current node
+   * @return the next visible node in the JTree. Return null if there are no
+   *         more.
+   */
+  Object getNextVisibleNode(Object node)
+  {
+    Object[] nodes = currentVisiblePath.getPath();
+    int i = 0;
+    while (i < nodes.length && !node.equals(nodes[i]))
+      i++;
+    // return the next node
+    if (i+1 < nodes.length)
+      return nodes[i+1];
+    return null;
   }
 } // BasicTreeUI
Index: javax/swing/plaf/metal/MetalTreeUI.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/metal/MetalTreeUI.java,v
retrieving revision 1.7
diff -u -r1.7 MetalTreeUI.java
--- javax/swing/plaf/metal/MetalTreeUI.java	28 Sep 2005 13:28:35 -0000	1.7
+++ javax/swing/plaf/metal/MetalTreeUI.java	5 Oct 2005 21:18:46 -0000
@@ -153,7 +153,11 @@
     TreeModel mod = tree.getModel();
     setModel(mod);
     if (mod != null)
-      tree.expandPath(new TreePath(mod.getRoot()));
+      {
+        TreePath path = new TreePath(mod.getRoot());
+        if (!tree.isExpanded(path))
+          toggleExpandState(path);
+      }
     treeSelectionModel = tree.getSelectionModel();
     drawingCache = new Hashtable();
     nodeDimensions = createNodeDimensions();
_______________________________________________
Classpath-patches mailing list
Classpath-patches@gnu.org
http://lists.gnu.org/mailman/listinfo/classpath-patches

Reply via email to