src/java.desktop/share/classes/javax/swing/tree/VariableHeightLayoutCache.java
changeset 48639 96ef7a0cf0b1
parent 47216 71c04702a3d5
child 52248 2e330da7cbf4
equal deleted inserted replaced
48351:80176afc8667 48639:96ef7a0cf0b1
   407      *
   407      *
   408      * @param e the <code>TreeModelEvent</code> of interest
   408      * @param e the <code>TreeModelEvent</code> of interest
   409      */
   409      */
   410     public void treeNodesChanged(TreeModelEvent e) {
   410     public void treeNodesChanged(TreeModelEvent e) {
   411         if(e != null) {
   411         if(e != null) {
   412             int               changedIndexs[];
   412             int               changedIndexs[]  = e.getChildIndices();
   413             TreeStateNode     changedNode;
   413             TreeStateNode     changedNode = getNodeForPath(
   414 
   414                     SwingUtilities2.getTreePath(e, getModel()), false, false);
   415             changedIndexs = e.getChildIndices();
   415 
   416             changedNode = getNodeForPath(SwingUtilities2.getTreePath(e, getModel()), false, false);
       
   417             if(changedNode != null) {
   416             if(changedNode != null) {
   418                 Object            changedValue = changedNode.getValue();
   417                 Object            changedValue = changedNode.getValue();
   419 
   418 
   420                 /* Update the size of the changed node, as well as all the
   419                 /* Update the size of the changed node, as well as all the
   421                    child indexs that are passed in. */
   420                    child indexs that are passed in. */
   422                 changedNode.updatePreferredSize();
   421                 changedNode.updatePreferredSize();
   423                 if(changedNode.hasBeenExpanded() && changedIndexs != null) {
   422                 if(changedNode.hasBeenExpanded() && changedIndexs != null) {
   424                     int                counter;
   423                     for(int index : changedIndexs) {
   425                     TreeStateNode      changedChildNode;
   424                         TreeStateNode changedChildNode = (TreeStateNode)changedNode
   426 
   425                                     .getChildAt(index);
   427                     for(counter = 0; counter < changedIndexs.length;
       
   428                         counter++) {
       
   429                         changedChildNode = (TreeStateNode)changedNode
       
   430                                     .getChildAt(changedIndexs[counter]);
       
   431                         /* Reset the user object. */
   426                         /* Reset the user object. */
   432                         changedChildNode.setUserObject
   427                         changedChildNode.setUserObject
   433                                     (treeModel.getChild(changedValue,
   428                                     (treeModel.getChild(changedValue, index));
   434                                                      changedIndexs[counter]));
       
   435                         changedChildNode.updatePreferredSize();
   429                         changedChildNode.updatePreferredSize();
   436                     }
   430                     }
   437                 }
   431                 }
   438                 else if (changedNode == root) {
   432                 else if (changedNode == root) {
   439                     // Null indicies for root indicates it changed.
   433                     // Null indicies for root indicates it changed.
   460      *
   454      *
   461      * @param e the <code>TreeModelEvent</code> of interest
   455      * @param e the <code>TreeModelEvent</code> of interest
   462      */
   456      */
   463     public void treeNodesInserted(TreeModelEvent e) {
   457     public void treeNodesInserted(TreeModelEvent e) {
   464         if(e != null) {
   458         if(e != null) {
   465             int               changedIndexs[];
   459             int               changedIndexs[] = e.getChildIndices();
   466             TreeStateNode     changedParentNode;
   460             TreeStateNode     changedParentNode = getNodeForPath(
   467 
   461                     SwingUtilities2.getTreePath(e, getModel()), false, false);
   468             changedIndexs = e.getChildIndices();
       
   469             changedParentNode = getNodeForPath(SwingUtilities2.getTreePath(e, getModel()), false, false);
       
   470             /* Only need to update the children if the node has been
   462             /* Only need to update the children if the node has been
   471                expanded once. */
   463                expanded once. */
   472             // PENDING(scott): make sure childIndexs is sorted!
   464             // PENDING(scott): make sure childIndexs is sorted!
   473             if(changedParentNode != null && changedIndexs != null &&
   465             if(changedParentNode != null && changedIndexs != null &&
   474                changedIndexs.length > 0) {
   466                changedIndexs.length > 0) {
   475                 if(changedParentNode.hasBeenExpanded()) {
   467                 if(changedParentNode.hasBeenExpanded()) {
   476                     boolean            makeVisible;
   468                     boolean   makeVisible =((changedParentNode == root &&
   477                     int                counter;
   469                                             !rootVisible) ||
   478                     Object             changedParent;
   470                                             (changedParentNode.getRow() != -1 &&
   479                     TreeStateNode      newNode;
   471                                                changedParentNode.isExpanded()));
   480                     int                oldChildCount = changedParentNode.
   472                     int  oldChildCount = changedParentNode.getChildCount();
   481                                           getChildCount();
   473 
   482 
   474                     for(int index : changedIndexs)
   483                     changedParent = changedParentNode.getValue();
       
   484                     makeVisible = ((changedParentNode == root &&
       
   485                                     !rootVisible) ||
       
   486                                    (changedParentNode.getRow() != -1 &&
       
   487                                     changedParentNode.isExpanded()));
       
   488                     for(counter = 0;counter < changedIndexs.length;counter++)
       
   489                     {
   475                     {
   490                         newNode = this.createNodeAt(changedParentNode,
   476                         this.createNodeAt(changedParentNode, index);
   491                                                     changedIndexs[counter]);
       
   492                     }
   477                     }
       
   478 
   493                     if(oldChildCount == 0) {
   479                     if(oldChildCount == 0) {
   494                         // Update the size of the parent.
   480                         // Update the size of the parent.
   495                         changedParentNode.updatePreferredSize();
   481                         changedParentNode.updatePreferredSize();
   496                     }
   482                     }
   497                     if(treeSelectionModel != null)
   483                     if(treeSelectionModel != null)
   641                   treeModel.getRoot() == null) ||
   627                   treeModel.getRoot() == null) ||
   642                  (changedPath != null && changedPath.getPathCount() == 1)))) {
   628                  (changedPath != null && changedPath.getPathCount() == 1)))) {
   643                 rebuild(true);
   629                 rebuild(true);
   644             }
   630             }
   645             else if(changedNode != null) {
   631             else if(changedNode != null) {
   646                 int                              nodeIndex, oldRow;
   632                 int                              nodeIndex;
   647                 TreeStateNode                    newNode, parent;
   633                 TreeStateNode                    newNode, parent;
   648                 boolean                          wasExpanded, wasVisible;
   634                 boolean                          wasExpanded, wasVisible;
   649                 int                              newIndex;
   635                 int                              newIndex;
   650 
   636 
   651                 wasExpanded = changedNode.isExpanded();
   637                 wasExpanded = changedNode.isExpanded();
   923       * Returns the index of the row containing location.  If there
   909       * Returns the index of the row containing location.  If there
   924       * are no rows, -1 is returned.  If location is beyond the last
   910       * are no rows, -1 is returned.  If location is beyond the last
   925       * row index, the last row index is returned.
   911       * row index, the last row index is returned.
   926       */
   912       */
   927     private int getRowContainingYLocation(int location) {
   913     private int getRowContainingYLocation(int location) {
       
   914         final int rows = getRowCount();
       
   915 
       
   916         if(rows <= 0)
       
   917             return -1;
   928         if(isFixedRowHeight()) {
   918         if(isFixedRowHeight()) {
   929             if(getRowCount() == 0)
   919             return Math.max(0, Math.min(rows - 1,
   930                 return -1;
       
   931             return Math.max(0, Math.min(getRowCount() - 1,
       
   932                                         location / getRowHeight()));
   920                                         location / getRowHeight()));
   933         }
   921         }
   934 
   922 
   935         int                    max, maxY, mid, min, minY;
   923         int max = rows, min = 0, mid = 0;
   936         TreeStateNode          node;
   924 
   937 
       
   938         if((max = getRowCount()) <= 0)
       
   939             return -1;
       
   940         mid = min = 0;
       
   941         while(min < max) {
   925         while(min < max) {
   942             mid = (max - min) / 2 + min;
   926             mid = (max - min) / 2 + min;
   943             node = (TreeStateNode)visibleNodes.elementAt(mid);
   927             TreeStateNode node = (TreeStateNode)visibleNodes.elementAt(mid);
   944             minY = node.getYOrigin();
   928             int minY = node.getYOrigin();
   945             maxY = minY + node.getPreferredHeight();
   929             int maxY = minY + node.getPreferredHeight();
   946             if(location < minY) {
   930             if(location < minY) {
   947                 max = mid - 1;
   931                 max = mid - 1;
   948             }
   932             }
   949             else if(location >= maxY) {
   933             else if(location >= maxY) {
   950                 min = mid + 1;
   934                 min = mid + 1;
   952             else
   936             else
   953                 break;
   937                 break;
   954         }
   938         }
   955         if(min == max) {
   939         if(min == max) {
   956             mid = min;
   940             mid = min;
   957             if(mid >= getRowCount())
   941             if(mid >= rows)
   958                 mid = getRowCount() - 1;
   942                 mid = rows - 1;
   959         }
   943         }
   960         return mid;
   944         return mid;
   961     }
   945     }
   962 
   946 
   963     /**
   947     /**
  1006             node = this.getNode(counter);
   990             node = this.getNode(counter);
  1007             nodeWidth = node.getPreferredWidth() + node.getXOrigin();
   991             nodeWidth = node.getPreferredWidth() + node.getXOrigin();
  1008             if(nodeWidth > maxWidth)
   992             if(nodeWidth > maxWidth)
  1009                 maxWidth = nodeWidth;
   993                 maxWidth = nodeWidth;
  1010         }
   994         }
       
   995 
  1011         return maxWidth;
   996         return maxWidth;
  1012     }
   997     }
  1013 
       
  1014     /**
   998     /**
  1015       * Responsible for creating a TreeStateNode that will be used
   999       * Responsible for creating a TreeStateNode that will be used
  1016       * to track display information about value.
  1000       * to track display information about value.
  1017       */
  1001       */
  1018     private TreeStateNode createNodeForValue(Object value) {
  1002     private TreeStateNode createNodeForValue(Object value) {
  1360             Rectangle       bounds = getNodeDimensions(this.getUserObject(),
  1344             Rectangle       bounds = getNodeDimensions(this.getUserObject(),
  1361                                                        index, getLevel(),
  1345                                                        index, getLevel(),
  1362                                                        isExpanded(),
  1346                                                        isExpanded(),
  1363                                                        boundsBuffer);
  1347                                                        boundsBuffer);
  1364 
  1348 
  1365             if(bounds == null) {
  1349             if(bounds == null || bounds.height == 0) {
  1366                 xOrigin = 0;
  1350                 xOrigin = 0;
  1367                 preferredWidth = preferredHeight = 0;
  1351                 preferredWidth = preferredHeight = 0;
  1368                 updateNodeSizes = true;
  1352                 updateNodeSizes = true;
  1369             }
  1353             } else {
  1370             else if(bounds.height == 0) {
       
  1371                 xOrigin = 0;
       
  1372                 preferredWidth = preferredHeight = 0;
       
  1373                 updateNodeSizes = true;
       
  1374             }
       
  1375             else {
       
  1376                 xOrigin = bounds.x;
  1354                 xOrigin = bounds.x;
  1377                 preferredWidth = bounds.width;
  1355                 preferredWidth = bounds.width;
  1378                 if(isFixedRowHeight())
  1356                 if(isFixedRowHeight())
  1379                     preferredHeight = getRowHeight();
  1357                     preferredHeight = getRowHeight();
  1380                 else
  1358                 else
  1475                 if (!hasBeenExpanded) {
  1453                 if (!hasBeenExpanded) {
  1476                     TreeStateNode  newNode;
  1454                     TreeStateNode  newNode;
  1477                     Object         realNode = getValue();
  1455                     Object         realNode = getValue();
  1478                     TreeModel      treeModel = getModel();
  1456                     TreeModel      treeModel = getModel();
  1479                     int            count = treeModel.getChildCount(realNode);
  1457                     int            count = treeModel.getChildCount(realNode);
  1480 
  1458                     int offset = originalRow == -1 ? -1 : originalRow + 1;
  1481                     hasBeenExpanded = true;
  1459                     hasBeenExpanded = true;
  1482                     if(originalRow == -1) {
  1460 
  1483                         for (int i = 0; i < count; i++) {
  1461                     for (int i = 0; i < count; i++) {
  1484                             newNode = createNodeForValue(treeModel.getChild
  1462                         newNode = createNodeForValue(treeModel.getChild
  1485                                                             (realNode, i));
  1463                                                         (realNode, i));
  1486                             this.add(newNode);
  1464                         this.add(newNode);
  1487                             newNode.updatePreferredSize(-1);
  1465                         newNode.updatePreferredSize(offset);
  1488                         }
       
  1489                     }
       
  1490                     else {
       
  1491                         int offset = originalRow + 1;
       
  1492                         for (int i = 0; i < count; i++) {
       
  1493                             newNode = createNodeForValue(treeModel.getChild
       
  1494                                                        (realNode, i));
       
  1495                             this.add(newNode);
       
  1496                             newNode.updatePreferredSize(offset);
       
  1497                         }
       
  1498                     }
  1466                     }
  1499                 }
  1467                 }
  1500 
  1468 
  1501                 int i = originalRow;
  1469                 int i = originalRow;
  1502                 Enumeration<TreeNode> cursor = preorderEnumeration();
  1470                 Enumeration<TreeNode> cursor = preorderEnumeration();
  1503                 cursor.nextElement(); // don't add me, I'm already in
  1471                 cursor.nextElement(); // don't add me, I'm already in
  1504 
  1472 
  1505                 int newYOrigin;
  1473                 int newYOrigin = isFixed || (this == root && !isRootVisible()) ?
  1506 
  1474                                     0 : getYOrigin() + this.getPreferredHeight();
  1507                 if(isFixed)
  1475 
  1508                     newYOrigin = 0;
       
  1509                 else if(this == root && !isRootVisible())
       
  1510                     newYOrigin = 0;
       
  1511                 else
       
  1512                     newYOrigin = getYOrigin() + this.getPreferredHeight();
       
  1513                 TreeStateNode   aNode;
  1476                 TreeStateNode   aNode;
  1514                 if(!isFixed) {
  1477                 if(!isFixed) {
  1515                     while (cursor.hasMoreElements()) {
  1478                     while (cursor.hasMoreElements()) {
  1516                         aNode = (TreeStateNode) cursor.nextElement();
  1479                         aNode = (TreeStateNode) cursor.nextElement();
  1517                         if(!updateNodeSizes && !aNode.hasValidSize())
  1480                         if(!updateNodeSizes && !aNode.hasValidSize())
  1742          * the number of children of parent.
  1705          * the number of children of parent.
  1743          */
  1706          */
  1744         protected boolean updateNextIndex() {
  1707         protected boolean updateNextIndex() {
  1745             // nextIndex == -1 identifies receiver, make sure is expanded
  1708             // nextIndex == -1 identifies receiver, make sure is expanded
  1746             // before descend.
  1709             // before descend.
  1747             if(nextIndex == -1 && !parent.isExpanded())
  1710             if((nextIndex == -1 && !parent.isExpanded()) ||
  1748                 return false;
  1711                 childCount == 0 || // Check that it can have kids
  1749 
  1712                 ++nextIndex >= childCount) // Make sure next index not beyond
  1750             // Check that it can have kids
  1713                                              // child count.
  1751             if(childCount == 0)
       
  1752                 return false;
       
  1753             // Make sure next index not beyond child count.
       
  1754             else if(++nextIndex >= childCount)
       
  1755                 return false;
  1714                 return false;
  1756 
  1715 
  1757             TreeStateNode       child = (TreeStateNode)parent.
  1716             TreeStateNode       child = (TreeStateNode)parent.
  1758                                         getChildAt(nextIndex);
  1717                                         getChildAt(nextIndex);
  1759 
  1718