/** * 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 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(); } } }
/** * Returns the row that the last item identified in path is visible at. Will return -1 if any of * the elements in path are not currently visible. */ public int getRowForPath(TreePath path) { if (path == null || root == null) return -1; FHTreeStateNode node = getNodeForPath(path, true, false); if (node != null) return node.getRow(); TreePath parentPath = path.getParentPath(); node = getNodeForPath(parentPath, true, false); if (node != null && node.isExpanded()) { return node.getRowToModelIndex( treeModel.getIndexOfChild( parentPath.getLastPathComponent(), path.getLastPathComponent())); } return -1; }
/** * Removes the child at <code>modelIndex</code>. <code>isChildVisible</code> should be true if * the receiver is visible and expanded. */ protected void removeChildAtModelIndex(int modelIndex, boolean isChildVisible) { FHTreeStateNode childNode = getChildAtModelIndex(modelIndex); if (childNode != null) { int row = childNode.getRow(); int index = getIndex(childNode); childNode.collapse(false); remove(index); adjustChildIndexs(index, -1); childCount--; if (isChildVisible) { // Adjust the rows. resetChildrenRowsFrom(row, index, modelIndex); } } else { int maxCounter = getChildCount(); FHTreeStateNode aChild; for (int counter = 0; counter < maxCounter; counter++) { aChild = (FHTreeStateNode) getChildAt(counter); if (aChild.childIndex >= modelIndex) { if (isChildVisible) { adjustRowBy(-1, counter); adjustRowCountBy(-1); } // Since matched and children are always sorted by // index, no need to continue testing with the // above. for (; counter < maxCounter; counter++) ((FHTreeStateNode) getChildAt(counter)).childIndex--; childCount--; return; } } // No children to adjust, but it was a child, so we still need // to adjust nodes after this one. if (isChildVisible) { adjustRowBy(-1, maxCounter); adjustRowCountBy(-1); } childCount--; } }