/** * Returns the bounds for the given node. If <code>childIndex</code> is -1, the bounds of <code> * parent</code> are returned, otherwise the bounds of the node at <code>childIndex</code> are * returned. */ private Rectangle getBounds(FHTreeStateNode parent, int childIndex, Rectangle placeIn) { boolean expanded; int level; int row; Object value; if (childIndex == -1) { // Getting bounds for parent row = parent.getRow(); value = parent.getUserObject(); expanded = parent.isExpanded(); level = parent.getLevel(); } else { row = parent.getRowToModelIndex(childIndex); value = treeModel.getChild(parent.getUserObject(), childIndex); expanded = false; level = parent.getLevel() + 1; } Rectangle bounds = getNodeDimensions(value, row, level, expanded, boundsBuffer); // No node dimensions, bail. if (bounds == null) return null; if (placeIn == null) placeIn = new Rectangle(); placeIn.x = bounds.x; placeIn.height = getRowHeight(); placeIn.y = row * placeIn.height; placeIn.width = bounds.width; return placeIn; }
/** * 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(); } } } }
/** * Updates <code>nextIndex</code> returning false if it is beyond the number of children of * parent. */ protected boolean updateNextIndex() { // nextIndex == -1 identifies receiver, make sure is expanded // before descend. if (nextIndex == -1 && !parent.isExpanded()) { return false; } // Check that it can have kids if (childCount == 0) { return false; } // Make sure next index not beyond child count. else if (++nextIndex >= childCount) { return false; } FHTreeStateNode child = parent.getChildAtModelIndex(nextIndex); if (child != null && child.isExpanded()) { parent = child; nextIndex = -1; childCount = treeModel.getChildCount(child.getUserObject()); } return true; }
protected TreePath getPath() { if (node == null) return null; if (isNodeParentNode) return node.getTreePath() .pathByAddingChild(treeModel.getChild(node.getUserObject(), childIndex)); return node.path; }
/** * Finds the next valid parent, this should be called when nextIndex is beyond the number of * children of the current parent. */ protected boolean findNextValidParent() { if (parent == root) { // mark as invalid! parent = null; return false; } while (parent != null) { FHTreeStateNode newParent = (FHTreeStateNode) parent.getParent(); if (newParent != null) { nextIndex = parent.childIndex; parent = newParent; childCount = treeModel.getChildCount(parent.getUserObject()); if (updateNextIndex()) return true; } else parent = null; } return false; }
/** @return next visible TreePath. */ public TreePath nextElement() { if (!hasMoreElements()) throw new NoSuchElementException("No more visible paths"); TreePath retObject; if (nextIndex == -1) retObject = parent.getTreePath(); else { FHTreeStateNode node = parent.getChildAtModelIndex(nextIndex); if (node == null) retObject = parent .getTreePath() .pathByAddingChild(treeModel.getChild(parent.getUserObject(), nextIndex)); else retObject = node.getTreePath(); } updateNextObject(); return retObject; }