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