| 902 |  | = | 902 |  | 
| 903 |  |  | 903 |  | 
| 904 |  |  | 904 |  | 
| 905 |  |  | 905 |  | 
| 906 |  |  | 906 |  | 
| 907 | private void updateNodeSizes(boolean updateAll) { |  | 907 | private void updateNodeSizes(boolean updateAll) { | 
| 908 | int                      aY, counter, maxCounter; | +- |  |  | 
| 909 | TreeStateNode            node; |  |  |  | 
| 910 |  | = | 908 |  | 
| 911 | updateNodeSizes = false; |  | 909 | updateNodeSizes = false; | 
|  |  | <> | 910 |  | 
| 912 | for(aY = counter = 0, maxCounter = visibleNodes.size(); |  | 911 | visibleNodes.stream().reduce(0, (a, b) -> { | 
| 913 | counter < maxCounter; counter++) { |  |  |  | 
| 914 | node = (TreeStateNode)visibleNodes.elementAt(counter); |  | 912 | TreeStateNode node = (TreeStateNode)b; | 
| 915 | node.setYOrigin(aY); |  | 913 | node.yOrigin = a; | 
| 916 | if(updateAll || !node.hasValidSize()) | = | 914 | if(updateAll || !node.hasValidSize()) | 
| 917 | node.updatePreferredSize(counter); | <> | 915 | node.updatePreferredSize(); | 
| 918 | aY += node.getPreferredHeight(); |  | 916 | return a + node.getPreferredHeight(); | 
|  |  |  | 917 | }, Integer::sum); | 
|  |  |  | 918 | //        for(aY = counter = 0, maxCounter = visibleNodes.size(); | 
|  |  |  | 919 | //            counter < maxCounter; counter++) { | 
|  |  |  | 920 | //            node = (TreeStateNode)visibleNodes.elementAt(counter); | 
|  |  |  | 921 | //            node.setYOrigin(aY); | 
|  |  |  | 922 | //            if(updateAll || !node.hasValidSize()) | 
|  |  |  | 923 | //                node.updatePreferredSize(counter); | 
|  |  |  | 924 | //            aY += node.getPreferredHeight(); | 
| 919 | } |  | 925 | //        } | 
| 920 | } | = | 926 | } | 
| 921 |  |  | 927 |  | 
| 922 |  |  | 928 |  | 
| 923 |  |  | 929 |  | 
| 924 |  |  | 930 |  | 
| 925 |  |  | 931 |  | 
| 926 |  |  | 932 |  | 
| 927 | private int getRowContainingYLocation(int location) { |  | 933 | private int getRowContainingYLocation(int location) { | 
| 928 | if(isFixedRowHeight()) { | <> | 934 | //handle the trivial reject case first, rather than | 
|  |  |  | 935 | //doing it twice. | 
| 929 | if(getRowCount() == 0) |  | 936 | if (getRowCount() == 0) | 
| 930 | return -1; |  | 937 | return -1; | 
|  |  |  | 938 |  | 
|  |  |  | 939 | if(isFixedRowHeight()) { | 
| 931 | return Math.max(0, Math.min(getRowCount() - 1, | = | 940 | return Math.max(0, Math.min(getRowCount() - 1, | 
| 932 | location / getRowHeight())); |  | 941 | location / getRowHeight())); | 
| 933 | } |  | 942 | } | 
| 934 |  |  | 943 |  | 
| 935 | int                    max, maxY, mid, min, minY; | <> |  |  | 
| 936 | TreeStateNode          node; |  |  |  | 
| 937 |  |  | 944 | //initialize the variables at the point of declaration | 
| 938 | if((max = getRowCount()) <= 0) |  | 945 | int  max = getRowCount(); | 
| 939 | return -1; |  | 946 | int min = 0; | 
| 940 | mid = min = 0; |  | 947 | int mid = 0; | 
|  |  |  | 948 | int maxY, minY; | 
|  |  |  | 949 |  | 
| 941 | while(min < max) { | = | 950 | while(min < max) { | 
| 942 | mid = (max - min) / 2 + min; |  | 951 | mid = (max - min) / 2 + min; | 
| 943 | node = (TreeStateNode)visibleNodes.elementAt(mid); | <> | 952 | TreeStateNode node = (TreeStateNode)visibleNodes.elementAt(mid); | 
| 944 | minY = node.getYOrigin(); | = | 953 | minY = node.getYOrigin(); | 
| 945 | maxY = minY + node.getPreferredHeight(); |  | 954 | maxY = minY + node.getPreferredHeight(); | 
| 946 | if(location < minY) { |  | 955 | if(location < minY) { | 
| 947 | max = mid - 1; |  | 956 | max = mid - 1; | 
| 948 | } |  | 957 | } | 
| 949 | else if(location >= maxY) { |  | 958 | else if(location >= maxY) { | 
|  | 
| 994 | } | = | 1003 | } | 
| 995 |  |  | 1004 |  | 
| 996 |  |  | 1005 |  | 
| 997 |  |  | 1006 |  | 
| 998 |  |  | 1007 |  | 
| 999 | private int getMaxNodeWidth() { |  | 1008 | private int getMaxNodeWidth() { | 
| 1000 | int                     maxWidth = 0; | <> |  |  | 
| 1001 | int                     nodeWidth; |  |  |  | 
| 1002 | int                     counter; |  |  |  | 
| 1003 | TreeStateNode           node; |  | 1009 | //use a single stream function to calculate the maximum, eliminating all the | 
|  |  |  | 1010 | //local variables, and the looping logic. | 
| 1004 |  |  | 1011 | return visibleNodes.stream().reduce(0, (a, b) -> { | 
| 1005 | for(counter = getRowCount() - 1;counter >= 0;counter--) { |  |  |  | 
| 1006 | node = this.getNode(counter); |  | 1012 | TreeStateNode node = (TreeStateNode)b; | 
| 1007 | nodeWidth = node.getPreferredWidth() + node.getXOrigin(); |  | 1013 | return Math.max(a, node.getPreferredWidth() + node.getXOrigin()); | 
| 1008 | if(nodeWidth > maxWidth) |  | 1014 | }, Math::max); | 
| 1009 | maxWidth = nodeWidth; |  |  |  | 
| 1010 | } |  |  |  | 
| 1011 | return maxWidth; |  |  |  | 
| 1012 | } | = | 1015 | } | 
| 1013 |  |  | 1016 |  | 
| 1014 |  |  | 1017 |  | 
| 1015 |  |  | 1018 |  | 
| 1016 |  |  | 1019 |  | 
| 1017 |  |  | 1020 |  | 
|  | 
| 1359 | protected void updatePreferredSize(int index) { | = | 1362 | protected void updatePreferredSize(int index) { | 
| 1360 | Rectangle       bounds = getNodeDimensions(this.getUserObject(), |  | 1363 | Rectangle       bounds = getNodeDimensions(this.getUserObject(), | 
| 1361 | index, getLevel(), |  | 1364 | index, getLevel(), | 
| 1362 | isExpanded(), |  | 1365 | isExpanded(), | 
| 1363 | boundsBuffer); |  | 1366 | boundsBuffer); | 
| 1364 |  |  | 1367 |  | 
| 1365 | if(bounds == null) { | <> |  |  | 
| 1366 | xOrigin = 0; |  |  |  | 
| 1367 | preferredWidth = preferredHeight = 0; |  |  |  | 
| 1368 | updateNodeSizes = true; |  |  |  | 
| 1369 | } |  | 1368 | //Merge the two conditions, so that code duplication | 
|  |  |  | 1369 | //can be avoided. | 
| 1370 | else if(bounds.height == 0) { |  | 1370 | if(bounds == null || bounds.height == 0) { | 
| 1371 | xOrigin = 0; | = | 1371 | xOrigin = 0; | 
| 1372 | preferredWidth = preferredHeight = 0; |  | 1372 | preferredWidth = preferredHeight = 0; | 
| 1373 | updateNodeSizes = true; |  | 1373 | updateNodeSizes = true; | 
| 1374 | } |  | 1374 | } | 
| 1375 | else { |  | 1375 | else { | 
| 1376 | xOrigin = bounds.x; |  | 1376 | xOrigin = bounds.x; | 
|  | 
| 1476 | TreeStateNode  newNode; | = | 1476 | TreeStateNode  newNode; | 
| 1477 | Object         realNode = getValue(); |  | 1477 | Object         realNode = getValue(); | 
| 1478 | TreeModel      treeModel = getModel(); |  | 1478 | TreeModel      treeModel = getModel(); | 
| 1479 | int            count = treeModel.getChildCount(realNode); |  | 1479 | int            count = treeModel.getChildCount(realNode); | 
| 1480 |  |  | 1480 |  | 
| 1481 | hasBeenExpanded = true; |  | 1481 | hasBeenExpanded = true; | 
|  |  | <> | 1482 |  | 
|  |  |  | 1483 | //Move the initialization of the offset variable into a conditional | 
|  |  |  | 1484 | //so that the repeated code can be removed. | 
|  |  |  | 1485 | int offset = originalRow == -1 ? originalRow : originalRow + 1; | 
| 1482 | if(originalRow == -1) { |  | 1486 |  | 
| 1483 | for (int i = 0; i < count; i++) { |  | 1487 | for (int i = 0; i < count; i++) { | 
| 1484 | newNode = createNodeForValue(treeModel.getChild |  | 1488 | newNode = createNodeForValue(treeModel.getChild | 
| 1485 | (realNode, i)); | = | 1489 | (realNode, i)); | 
| 1486 | this.add(newNode); | <> | 1490 | this.add(newNode); | 
| 1487 | newNode.updatePreferredSize(-1); |  |  |  | 
| 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); |  | 1491 | newNode.updatePreferredSize(offset); | 
| 1497 | } |  |  |  | 
| 1498 | } | = | 1492 | } | 
| 1499 | } |  | 1493 | } | 
| 1500 |  |  | 1494 |  | 
| 1501 | int i = originalRow; |  | 1495 | int i = originalRow; | 
| 1502 | Enumeration<TreeNode> cursor = preorderEnumeration(); |  | 1496 | Enumeration<TreeNode> cursor = preorderEnumeration(); | 
|  |  | -+ | 1497 |  | 
| 1503 | cursor.nextElement(); | = | 1498 | cursor.nextElement(); | 
| 1504 |  |  | 1499 |  | 
| 1505 | int newYOrigin; | <> |  |  | 
| 1506 |  |  |  |  | 
| 1507 | if(isFixed) |  |  |  | 
| 1508 | newYOrigin = 0; |  |  |  | 
| 1509 | else if(this == root && !isRootVisible()) |  | 1500 | int newYOrigin = (isFixed || (this == root && !rootVisible)) ? 0 | 
| 1510 | newYOrigin = 0; |  |  |  | 
| 1511 | else |  |  |  | 
| 1512 | newYOrigin = getYOrigin() + this.getPreferredHeight(); |  | 1501 | : yOrigin + this.preferredHeight; | 
|  |  |  | 1502 |  | 
| 1513 | TreeStateNode   aNode; | = | 1503 | TreeStateNode   aNode; | 
| 1514 | if(!isFixed) { |  | 1504 | if(!isFixed) { | 
| 1515 | while (cursor.hasMoreElements()) { |  | 1505 | while (cursor.hasMoreElements()) { | 
| 1516 | aNode = (TreeStateNode) cursor.nextElement(); |  | 1506 | aNode = (TreeStateNode) cursor.nextElement(); | 
| 1517 | if(!updateNodeSizes && !aNode.hasValidSize()) |  | 1507 | if(!updateNodeSizes && !aNode.hasValidSize()) | 
| 1518 | aNode.updatePreferredSize(i + 1); |  | 1508 | aNode.updatePreferredSize(i + 1); | 
|  | 
| 1533 |  | = | 1523 |  | 
| 1534 | if(!isFixed && ++i < getRowCount()) { |  | 1524 | if(!isFixed && ++i < getRowCount()) { | 
| 1535 | int              counter; |  | 1525 | int              counter; | 
| 1536 | int              heightDiff = newYOrigin - |  | 1526 | int              heightDiff = newYOrigin - | 
| 1537 | (getYOrigin() + getPreferredHeight()) + |  | 1527 | (getYOrigin() + getPreferredHeight()) + | 
| 1538 | (getPreferredHeight() - startHeight); |  | 1528 | (getPreferredHeight() - startHeight); | 
|  |  | <> | 1529 |  | 
| 1539 |  |  | 1530 | //Use a forEach function instead of a raw loop. | 
| 1540 | for(counter = visibleNodes.size() - 1;counter >= i; |  | 1531 | visibleNodes.forEach( o -> | 
| 1541 | counter--) |  |  |  | 
| 1542 | ((TreeStateNode)visibleNodes.elementAt(counter)). |  |  |  | 
| 1543 | shiftYOriginBy(heightDiff); |  | 1532 | ((TreeStateNode)o).shiftYOriginBy(heightDiff)); | 
| 1544 | } | = | 1533 | } | 
| 1545 | didAdjustTree(); |  | 1534 | didAdjustTree(); | 
| 1546 | visibleNodesChanged(); |  | 1535 | visibleNodesChanged(); | 
| 1547 | } |  | 1536 | } | 
| 1548 |  |  | 1537 |  | 
| 1549 |  |  | 1538 |  | 
|  | 
| 1741 |  | = | 1730 |  | 
| 1742 |  |  | 1731 |  | 
| 1743 |  |  | 1732 |  | 
| 1744 | protected boolean updateNextIndex() { |  | 1733 | protected boolean updateNextIndex() { | 
| 1745 |  |  | 1734 |  | 
| 1746 |  |  | 1735 |  | 
|  |  | <> | 1736 | //Move the conditions into one if, so as to collapse all the return | 
|  |  |  | 1737 | //statements into one. | 
|  |  |  | 1738 | //Also, donot update the nextIndex variable when determining if it is | 
|  |  |  | 1739 | //within the bounds, to avoid nextIndex having values greater than the | 
|  |  |  | 1740 | //size of the container. | 
| 1747 | if(nextIndex == -1 && !parent.isExpanded()) |  | 1741 | if(nextIndex == -1 && !parent.isExpanded() || | 
| 1748 | return false; |  |  |  | 
| 1749 |  |  |  |  | 
| 1750 | // Check that it can have kids |  |  |  | 
| 1751 | if(childCount == 0) |  | 1742 | childCount == 0 || // Check that it can have kids | 
| 1752 | return false; |  |  |  | 
| 1753 | // Make sure next index not beyond child count. |  |  |  | 
| 1754 | else if(++nextIndex >= childCount) |  | 1743 | nextIndex + 1 >= childCount) // Make sure next index not beyond child count. | 
| 1755 | return false; | = | 1744 | return false; | 
| 1756 |  |  | 1745 |  | 
|  |  | -+ | 1746 | ++nextIndex; | 
| 1757 | TreeStateNode       child = (TreeStateNode)parent. | = | 1747 | TreeStateNode       child = (TreeStateNode)parent. | 
| 1758 | getChildAt(nextIndex); |  | 1748 | getChildAt(nextIndex); | 
| 1759 |  |  | 1749 |  | 
| 1760 | if(child != null && child.isExpanded()) { |  | 1750 | if(child != null && child.isExpanded()) { | 
| 1761 | parent = child; |  | 1751 | parent = child; | 
| 1762 | nextIndex = -1; |  | 1752 | nextIndex = -1; | 
| 1763 | childCount = child.getChildCount(); |  | 1753 | childCount = child.getChildCount(); | 
| 1764 | } |  | 1754 | } | 
| 1765 | return true; |  | 1755 | return true; | 
| 1766 | } |  | 1756 | } | 
| 1767 | } |  | 1757 | } | 
| 1768 | } |  | 1758 | } |