/** * Invoked after the tree has drastically changed structure from a given node down. If the path * returned by e.getPath() is of length one and the first element does not identify the current * root node the first element should become the new root of the tree. * * <p>e.path() holds the path to the node. * * <p>e.childIndices() returns null. */ public void treeStructureChanged(TreeModelEvent e) { if (e != null) { TreePath changedPath = SwingUtilities2.getTreePath(e, getModel()); FHTreeStateNode changedNode = getNodeForPath(changedPath, false, false); // Check if root has changed, either to a null root, or // to an entirely new root. if (changedNode == root || (changedNode == null && ((changedPath == null && treeModel != null && treeModel.getRoot() == null) || (changedPath != null && changedPath.getPathCount() <= 1)))) { rebuild(true); } else if (changedNode != null) { boolean wasExpanded, wasVisible; FHTreeStateNode parent = (FHTreeStateNode) changedNode.getParent(); wasExpanded = changedNode.isExpanded(); wasVisible = changedNode.isVisible(); int index = parent.getIndex(changedNode); changedNode.collapse(false); parent.remove(index); if (wasVisible && wasExpanded) { int row = changedNode.getRow(); parent.resetChildrenRowsFrom(row, index, changedNode.getChildIndex()); changedNode = getNodeForPath(changedPath, false, true); changedNode.expand(); } if (treeSelectionModel != null && wasVisible && wasExpanded) treeSelectionModel.resetRowSelection(); if (wasVisible) this.visibleNodesChanged(); } } }
/** * Invoked after nodes have been removed from the tree. Note that if a subtree is removed from the * tree, this method may only be invoked once for the root of the removed subtree, not once for * each individual set of siblings removed. * * <p>e.path() returns the former parent of the deleted nodes. * * <p>e.childIndices() returns the indices the nodes had before they were deleted in ascending * order. */ public void treeNodesRemoved(TreeModelEvent e) { if (e != null) { int changedIndexs[]; int maxCounter; TreePath parentPath = SwingUtilities2.getTreePath(e, getModel()); FHTreeStateNode changedParentNode = getNodeForPath(parentPath, false, false); changedIndexs = e.getChildIndices(); // PENDING(scott): make sure that changedIndexs are sorted in // ascending order. if (changedParentNode != null && changedIndexs != null && (maxCounter = changedIndexs.length) > 0) { Object[] children = e.getChildren(); boolean isVisible = (changedParentNode.isVisible() && changedParentNode.isExpanded()); for (int counter = maxCounter - 1; counter >= 0; counter--) { changedParentNode.removeChildAtModelIndex(changedIndexs[counter], isVisible); } if (isVisible) { if (treeSelectionModel != null) treeSelectionModel.resetRowSelection(); if (treeModel.getChildCount(changedParentNode.getUserObject()) == 0 && changedParentNode.isLeaf()) { // Node has become a leaf, collapse it. changedParentNode.collapse(false); } visibleNodesChanged(); } else if (changedParentNode.isVisible()) visibleNodesChanged(); } } }
/** * Invoked after a node (or a set of siblings) has changed in some way. The node(s) have not * changed locations in the tree or altered their children arrays, but other attributes have * changed and may affect presentation. Example: the name of a file has changed, but it is in the * same location in the file system. * * <p>e.path() returns the path the parent of the changed node(s). * * <p>e.childIndices() returns the index(es) of the changed node(s). */ public void treeNodesChanged(TreeModelEvent e) { if (e != null) { int changedIndexs[]; FHTreeStateNode changedParent = getNodeForPath(SwingUtilities2.getTreePath(e, getModel()), false, false); int maxCounter; changedIndexs = e.getChildIndices(); /* Only need to update the children if the node has been expanded once. */ // PENDING(scott): make sure childIndexs is sorted! if (changedParent != null) { if (changedIndexs != null && (maxCounter = changedIndexs.length) > 0) { Object parentValue = changedParent.getUserObject(); for (int counter = 0; counter < maxCounter; counter++) { FHTreeStateNode child = changedParent.getChildAtModelIndex(changedIndexs[counter]); if (child != null) { child.setUserObject(treeModel.getChild(parentValue, changedIndexs[counter])); } } if (changedParent.isVisible() && changedParent.isExpanded()) visibleNodesChanged(); } // Null for root indicates it changed. else if (changedParent == root && changedParent.isVisible() && changedParent.isExpanded()) { visibleNodesChanged(); } } } }
/** * Invoked after nodes have been inserted into the tree. * * <p>e.path() returns the parent of the new nodes * * <p>e.childIndices() returns the indices of the new nodes in ascending order. */ public void treeNodesInserted(TreeModelEvent e) { if (e != null) { int changedIndexs[]; FHTreeStateNode changedParent = getNodeForPath(SwingUtilities2.getTreePath(e, getModel()), false, false); int maxCounter; changedIndexs = e.getChildIndices(); /* Only need to update the children if the node has been expanded once. */ // PENDING(scott): make sure childIndexs is sorted! if (changedParent != null && changedIndexs != null && (maxCounter = changedIndexs.length) > 0) { boolean isVisible = (changedParent.isVisible() && changedParent.isExpanded()); for (int counter = 0; counter < maxCounter; counter++) { changedParent.childInsertedAtModelIndex(changedIndexs[counter], isVisible); } if (isVisible && treeSelectionModel != null) treeSelectionModel.resetRowSelection(); if (changedParent.isVisible()) this.visibleNodesChanged(); } } }