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 |
} |