Methods Summary |
---|
private void | addMapping(javax.swing.tree.VariableHeightLayoutCache$TreeStateNode node)Adds a mapping for node.
treePathMapping.put(node.getTreePath(), node);
|
private javax.swing.tree.VariableHeightLayoutCache$TreeStateNode | createNodeAt(javax.swing.tree.VariableHeightLayoutCache$TreeStateNode parent, int childIndex)Creates a new node to represent the node at childIndex in
parents children. This should be called if the node doesn't
already exist and parent has been expanded at least once.
The newly created node will be made visible if parent is
currently expanded. This does not update the position of any
cells, nor update the selection if it needs to be. If succesful
in creating the new TreeStateNode, it is returned, otherwise
null is returned.
boolean isParentRoot;
Object newValue;
TreeStateNode newChildNode;
newValue = treeModel.getChild(parent.getValue(), childIndex);
newChildNode = createNodeForValue(newValue);
parent.insert(newChildNode, childIndex);
newChildNode.updatePreferredSize(-1);
isParentRoot = (parent == root);
if(newChildNode != null && parent.isExpanded() &&
(parent.getRow() != -1 || isParentRoot)) {
int newRow;
/* Find the new row to insert this newly visible node at. */
if(childIndex == 0) {
if(isParentRoot && !isRootVisible())
newRow = 0;
else
newRow = parent.getRow() + 1;
}
else if(childIndex == parent.getChildCount())
newRow = parent.getLastVisibleNode().getRow() + 1;
else {
TreeStateNode previousNode;
previousNode = (TreeStateNode)parent.
getChildAt(childIndex - 1);
newRow = previousNode.getLastVisibleNode().getRow() + 1;
}
visibleNodes.insertElementAt(newChildNode, newRow);
}
return newChildNode;
|
private javax.swing.tree.VariableHeightLayoutCache$TreeStateNode | createNodeForValue(java.lang.Object value)Responsible for creating a TreeStateNode that will be used
to track display information about value.
return new TreeStateNode(value);
|
private void | ensurePathIsExpanded(javax.swing.tree.TreePath aPath, boolean expandLast)Ensures that all the path components in path are expanded, accept
for the last component which will only be expanded if expandLast
is true.
Returns true if succesful in finding the path.
if(aPath != null) {
// Make sure the last entry isn't a leaf.
if(treeModel.isLeaf(aPath.getLastPathComponent())) {
aPath = aPath.getParentPath();
expandLast = true;
}
if(aPath != null) {
TreeStateNode lastNode = getNodeForPath(aPath, false,
true);
if(lastNode != null) {
lastNode.makeVisible();
if(expandLast)
lastNode.expand();
}
}
}
|
private java.awt.Rectangle | getBounds(int row, java.awt.Rectangle placeIn)Retursn the bounds for row, row by reference in
placeIn . If placeIn is null a new
Rectangle will be created and returned.
if(updateNodeSizes)
updateNodeSizes(false);
if(row >= 0 && row < getRowCount()) {
return getNode(row).getNodeBounds(placeIn);
}
return null;
|
public java.awt.Rectangle | getBounds(javax.swing.tree.TreePath path, java.awt.Rectangle placeIn)Returns the Rectangle enclosing the label portion
into which the item identified by path will be drawn.
TreeStateNode node = getNodeForPath(path, true, false);
if(node != null) {
if(updateNodeSizes)
updateNodeSizes(false);
return node.getNodeBounds(placeIn);
}
return null;
|
public boolean | getExpandedState(javax.swing.tree.TreePath path)Returns true if the path is expanded, and visible.
TreeStateNode node = getNodeForPath(path, true, false);
return (node != null) ? (node.isVisible() && node.isExpanded()) :
false;
|
private javax.swing.tree.VariableHeightLayoutCache$TreeStateNode | getMapping(javax.swing.tree.TreePath path)Returns the node previously added for path . This may
return null, if you to create a node use getNodeForPath.
return (TreeStateNode)treePathMapping.get(path);
|
private int | getMaxNodeWidth()Returns the maximum node width.
int maxWidth = 0;
int nodeWidth;
int counter;
TreeStateNode node;
for(counter = getRowCount() - 1;counter >= 0;counter--) {
node = this.getNode(counter);
nodeWidth = node.getPreferredWidth() + node.getXOrigin();
if(nodeWidth > maxWidth)
maxWidth = nodeWidth;
}
return maxWidth;
|
private javax.swing.tree.VariableHeightLayoutCache$TreeStateNode | getNode(int row)Returns the AbstractTreeUI.VisibleNode displayed at the given row
return (TreeStateNode)visibleNodes.elementAt(row);
|
private javax.swing.tree.VariableHeightLayoutCache$TreeStateNode | getNodeForPath(javax.swing.tree.TreePath path, boolean onlyIfVisible, boolean shouldCreate)Returns the TreeStateNode identified by path. This mirrors
the behavior of getNodeForPath, but tries to take advantage of
path if it is an instance of AbstractTreePath.
if(path != null) {
TreeStateNode node;
node = getMapping(path);
if(node != null) {
if(onlyIfVisible && !node.isVisible())
return null;
return node;
}
// Check all the parent paths, until a match is found.
Stack paths;
if(tempStacks.size() == 0) {
paths = new Stack();
}
else {
paths = (Stack)tempStacks.pop();
}
try {
paths.push(path);
path = path.getParentPath();
node = null;
while(path != null) {
node = getMapping(path);
if(node != null) {
// Found a match, create entries for all paths in
// paths.
while(node != null && paths.size() > 0) {
path = (TreePath)paths.pop();
node.getLoadedChildren(shouldCreate);
int childIndex = treeModel.
getIndexOfChild(node.getUserObject(),
path.getLastPathComponent());
if(childIndex == -1 ||
childIndex >= node.getChildCount() ||
(onlyIfVisible && !node.isVisible())) {
node = null;
}
else
node = (TreeStateNode)node.getChildAt
(childIndex);
}
return node;
}
paths.push(path);
path = path.getParentPath();
}
}
finally {
paths.removeAllElements();
tempStacks.push(paths);
}
// If we get here it means they share a different root!
// We could throw an exception...
}
return null;
|
public javax.swing.tree.TreePath | getPathClosestTo(int x, int y)Returns the path to the node that is closest to x,y. If
there is nothing currently visible this will return null ,
otherwise it will always return a valid path.
If you need to test if the
returned object is exactly at x, y you should get the bounds for
the returned path and test x, y against that.
if(getRowCount() == 0)
return null;
if(updateNodeSizes)
updateNodeSizes(false);
int row = getRowContainingYLocation(y);
return getNode(row).getTreePath();
|
public javax.swing.tree.TreePath | getPathForRow(int row)Returns the path for row . If row
is not visible, null is returned.
if(row >= 0 && row < getRowCount()) {
return getNode(row).getTreePath();
}
return null;
|
public int | getPreferredHeight()Returns the preferred height.
// Get the height
int rowCount = getRowCount();
if(rowCount > 0) {
TreeStateNode node = getNode(rowCount - 1);
return node.getYOrigin() + node.getPreferredHeight();
}
return 0;
|
public int | getPreferredWidth(java.awt.Rectangle bounds)Returns the preferred width and height for the region in
visibleRegion .
if(updateNodeSizes)
updateNodeSizes(false);
return getMaxNodeWidth();
|
private int | getRowContainingYLocation(int location)Returns the index of the row containing location. If there
are no rows, -1 is returned. If location is beyond the last
row index, the last row index is returned.
if(isFixedRowHeight()) {
if(getRowCount() == 0)
return -1;
return Math.max(0, Math.min(getRowCount() - 1,
location / getRowHeight()));
}
int max, maxY, mid, min, minY;
TreeStateNode node;
if((max = getRowCount()) <= 0)
return -1;
mid = min = 0;
while(min < max) {
mid = (max - min) / 2 + min;
node = (TreeStateNode)visibleNodes.elementAt(mid);
minY = node.getYOrigin();
maxY = minY + node.getPreferredHeight();
if(location < minY) {
max = mid - 1;
}
else if(location >= maxY) {
min = mid + 1;
}
else
break;
}
if(min == max) {
mid = min;
if(mid >= getRowCount())
mid = getRowCount() - 1;
}
return mid;
|
public int | getRowCount()Returns the number of visible rows.
return visibleNodes.size();
|
public int | getRowForPath(javax.swing.tree.TreePath path)Returns the row where the last item identified in path is visible.
Will return -1 if any of the elements in path are not
currently visible.
if(path == null)
return -1;
TreeStateNode visNode = getNodeForPath(path, true, false);
if(visNode != null)
return visNode.getRow();
return -1;
|
public int | getVisibleChildCount(javax.swing.tree.TreePath path)Returns the number of visible children for path .
TreeStateNode node = getNodeForPath(path, true, false);
return (node != null) ? node.getVisibleChildCount() : 0;
|
public java.util.Enumeration | getVisiblePathsFrom(javax.swing.tree.TreePath path)Returns an Enumerator that increments over the visible paths
starting at the passed in location. The ordering of the enumeration
is based on how the paths are displayed.
TreeStateNode node = getNodeForPath(path, true, false);
if(node != null) {
return new VisibleTreeStateNodeEnumeration(node);
}
return null;
|
public void | invalidatePathBounds(javax.swing.tree.TreePath path)Instructs the LayoutCache that the bounds for
path are invalid, and need to be updated.
TreeStateNode node = getNodeForPath(path, true, false);
if(node != null) {
node.markSizeInvalid();
if(node.isVisible())
updateYLocationsFrom(node.getRow());
}
|
public void | invalidateSizes()Informs the TreeState that it needs to recalculate
all the sizes it is referencing.
if(root != null)
root.deepMarkSizeInvalid();
if(!isFixedRowHeight() && visibleNodes.size() > 0) {
updateNodeSizes(true);
}
|
public boolean | isExpanded(javax.swing.tree.TreePath path)Returns true if the value identified by path is
currently expanded.
if(path != null) {
TreeStateNode lastNode = getNodeForPath(path, true, false);
return (lastNode != null && lastNode.isExpanded());
}
return false;
|
private void | rebuild(boolean clearSelection)Completely rebuild the tree, all expanded state, and node caches are
removed. All nodes are collapsed, except the root.
Object rootObject;
treePathMapping.clear();
if(treeModel != null && (rootObject = treeModel.getRoot()) != null) {
root = createNodeForValue(rootObject);
root.path = new TreePath(rootObject);
addMapping(root);
root.updatePreferredSize(0);
visibleNodes.removeAllElements();
if (isRootVisible())
visibleNodes.addElement(root);
if(!root.isExpanded())
root.expand();
else {
Enumeration cursor = root.children();
while(cursor.hasMoreElements()) {
visibleNodes.addElement(cursor.nextElement());
}
if(!isFixedRowHeight())
updateYLocationsFrom(0);
}
}
else {
visibleNodes.removeAllElements();
root = null;
}
if(clearSelection && treeSelectionModel != null) {
treeSelectionModel.clearSelection();
}
this.visibleNodesChanged();
|
private void | removeMapping(javax.swing.tree.VariableHeightLayoutCache$TreeStateNode node)Removes the mapping for a previously added node.
treePathMapping.remove(node.getTreePath());
|
public void | setExpandedState(javax.swing.tree.TreePath path, boolean isExpanded)Marks the path path expanded state to
isExpanded .
if(path != null) {
if(isExpanded)
ensurePathIsExpanded(path, true);
else {
TreeStateNode node = getNodeForPath(path, false, true);
if(node != null) {
node.makeVisible();
node.collapse();
}
}
}
|
public void | setModel(javax.swing.tree.TreeModel newModel)Sets the TreeModel that will provide the data.
super.setModel(newModel);
rebuild(false);
|
public void | setNodeDimensions(NodeDimensions nd)Sets the renderer that is responsible for drawing nodes in the tree.
super.setNodeDimensions(nd);
invalidateSizes();
visibleNodesChanged();
|
public void | setRootVisible(boolean rootVisible)Determines whether or not the root node from
the TreeModel is visible.
if(isRootVisible() != rootVisible && root != null) {
if(rootVisible) {
root.updatePreferredSize(0);
visibleNodes.insertElementAt(root, 0);
}
else if(visibleNodes.size() > 0) {
visibleNodes.removeElementAt(0);
if(treeSelectionModel != null)
treeSelectionModel.removeSelectionPath
(root.getTreePath());
}
if(treeSelectionModel != null)
treeSelectionModel.resetRowSelection();
if(getRowCount() > 0)
getNode(0).setYOrigin(0);
updateYLocationsFrom(0);
visibleNodesChanged();
}
super.setRootVisible(rootVisible);
|
public void | setRowHeight(int rowHeight)Sets the height of each cell. If the specified value
is less than or equal to zero the current cell renderer is
queried for each row's height.
if(rowHeight != getRowHeight()) {
super.setRowHeight(rowHeight);
invalidateSizes();
this.visibleNodesChanged();
}
|
public void | treeNodesChanged(javax.swing.event.TreeModelEvent e)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.
e.path returns the path the parent of the
changed node(s).
e.childIndices returns the index(es) of the
changed node(s).
if(e != null) {
int changedIndexs[];
TreeStateNode changedNode;
changedIndexs = e.getChildIndices();
changedNode = getNodeForPath(e.getTreePath(), false, false);
if(changedNode != null) {
Object changedValue = changedNode.getValue();
/* Update the size of the changed node, as well as all the
child indexs that are passed in. */
changedNode.updatePreferredSize();
if(changedNode.hasBeenExpanded() && changedIndexs != null) {
int counter;
TreeStateNode changedChildNode;
for(counter = 0; counter < changedIndexs.length;
counter++) {
changedChildNode = (TreeStateNode)changedNode
.getChildAt(changedIndexs[counter]);
/* Reset the user object. */
changedChildNode.setUserObject
(treeModel.getChild(changedValue,
changedIndexs[counter]));
changedChildNode.updatePreferredSize();
}
}
else if (changedNode == root) {
// Null indicies for root indicates it changed.
changedNode.updatePreferredSize();
}
if(!isFixedRowHeight()) {
int aRow = changedNode.getRow();
if(aRow != -1)
this.updateYLocationsFrom(aRow);
}
this.visibleNodesChanged();
}
}
|
public void | treeNodesInserted(javax.swing.event.TreeModelEvent e)Invoked after nodes have been inserted into the tree.
e.path returns the parent of the new nodes.
e.childIndices returns the indices of the new nodes in
ascending order.
if(e != null) {
int changedIndexs[];
TreeStateNode changedParentNode;
changedIndexs = e.getChildIndices();
changedParentNode = getNodeForPath(e.getTreePath(), false, false);
/* Only need to update the children if the node has been
expanded once. */
// PENDING(scott): make sure childIndexs is sorted!
if(changedParentNode != null && changedIndexs != null &&
changedIndexs.length > 0) {
if(changedParentNode.hasBeenExpanded()) {
boolean makeVisible;
int counter;
Object changedParent;
TreeStateNode newNode;
int oldChildCount = changedParentNode.
getChildCount();
changedParent = changedParentNode.getValue();
makeVisible = ((changedParentNode == root &&
!rootVisible) ||
(changedParentNode.getRow() != -1 &&
changedParentNode.isExpanded()));
for(counter = 0;counter < changedIndexs.length;counter++)
{
newNode = this.createNodeAt(changedParentNode,
changedIndexs[counter]);
}
if(oldChildCount == 0) {
// Update the size of the parent.
changedParentNode.updatePreferredSize();
}
if(treeSelectionModel != null)
treeSelectionModel.resetRowSelection();
/* Update the y origins from the index of the parent
to the end of the visible rows. */
if(!isFixedRowHeight() && (makeVisible ||
(oldChildCount == 0 &&
changedParentNode.isVisible()))) {
if(changedParentNode == root)
this.updateYLocationsFrom(0);
else
this.updateYLocationsFrom(changedParentNode.
getRow());
this.visibleNodesChanged();
}
else if(makeVisible)
this.visibleNodesChanged();
}
else if(treeModel.getChildCount(changedParentNode.getValue())
- changedIndexs.length == 0) {
changedParentNode.updatePreferredSize();
if(!isFixedRowHeight() && changedParentNode.isVisible())
updateYLocationsFrom(changedParentNode.getRow());
}
}
}
|
public void | treeNodesRemoved(javax.swing.event.TreeModelEvent e)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.
e.path returns the former parent of the deleted nodes.
e.childIndices returns the indices the nodes had
before they were deleted in ascending order.
if(e != null) {
int changedIndexs[];
TreeStateNode changedParentNode;
changedIndexs = e.getChildIndices();
changedParentNode = getNodeForPath(e.getTreePath(), false, false);
// PENDING(scott): make sure that changedIndexs are sorted in
// ascending order.
if(changedParentNode != null && changedIndexs != null &&
changedIndexs.length > 0) {
if(changedParentNode.hasBeenExpanded()) {
boolean makeInvisible;
int counter;
int removedRow;
TreeStateNode removedNode;
makeInvisible = ((changedParentNode == root &&
!rootVisible) ||
(changedParentNode.getRow() != -1 &&
changedParentNode.isExpanded()));
for(counter = changedIndexs.length - 1;counter >= 0;
counter--) {
removedNode = (TreeStateNode)changedParentNode.
getChildAt(changedIndexs[counter]);
if(removedNode.isExpanded()) {
removedNode.collapse(false);
}
/* Let the selection model now. */
if(makeInvisible) {
removedRow = removedNode.getRow();
if(removedRow != -1) {
visibleNodes.removeElementAt(removedRow);
}
}
changedParentNode.remove(changedIndexs[counter]);
}
if(changedParentNode.getChildCount() == 0) {
// Update the size of the parent.
changedParentNode.updatePreferredSize();
if (changedParentNode.isExpanded() &&
changedParentNode.isLeaf()) {
// Node has become a leaf, collapse it.
changedParentNode.collapse(false);
}
}
if(treeSelectionModel != null)
treeSelectionModel.resetRowSelection();
/* Update the y origins from the index of the parent
to the end of the visible rows. */
if(!isFixedRowHeight() && (makeInvisible ||
(changedParentNode.getChildCount() == 0 &&
changedParentNode.isVisible()))) {
if(changedParentNode == root) {
/* It is possible for first row to have been
removed if the root isn't visible, in which
case ylocations will be off! */
if(getRowCount() > 0)
getNode(0).setYOrigin(0);
updateYLocationsFrom(0);
}
else
updateYLocationsFrom(changedParentNode.getRow());
this.visibleNodesChanged();
}
else if(makeInvisible)
this.visibleNodesChanged();
}
else if(treeModel.getChildCount(changedParentNode.getValue())
== 0) {
changedParentNode.updatePreferredSize();
if(!isFixedRowHeight() && changedParentNode.isVisible())
this.updateYLocationsFrom(changedParentNode.getRow());
}
}
}
|
public void | treeStructureChanged(javax.swing.event.TreeModelEvent e)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.
e.path holds the path to the node.
e.childIndices returns null .
if(e != null)
{
TreePath changedPath = e.getTreePath();
TreeStateNode changedNode;
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) {
int nodeIndex, oldRow;
TreeStateNode newNode, parent;
boolean wasExpanded, wasVisible;
int newIndex;
wasExpanded = changedNode.isExpanded();
wasVisible = (changedNode.getRow() != -1);
/* Remove the current node and recreate a new one. */
parent = (TreeStateNode)changedNode.getParent();
nodeIndex = parent.getIndex(changedNode);
if(wasVisible && wasExpanded) {
changedNode.collapse(false);
}
if(wasVisible)
visibleNodes.removeElement(changedNode);
changedNode.removeFromParent();
createNodeAt(parent, nodeIndex);
newNode = (TreeStateNode)parent.getChildAt(nodeIndex);
if(wasVisible && wasExpanded)
newNode.expand(false);
newIndex = newNode.getRow();
if(!isFixedRowHeight() && wasVisible) {
if(newIndex == 0)
updateYLocationsFrom(newIndex);
else
updateYLocationsFrom(newIndex - 1);
this.visibleNodesChanged();
}
else if(wasVisible)
this.visibleNodesChanged();
}
}
|
private void | updateNodeSizes(boolean updateAll)Resets the y origin of all the visible nodes as well as messaging
all the visible nodes to updatePreferredSize(). You should not
normally have to call this. Expanding and contracting the nodes
automaticly adjusts the locations.
updateAll determines if updatePreferredSize() is call on all nodes
or just those that don't have a valid size.
int aY, counter, maxCounter;
TreeStateNode node;
updateNodeSizes = false;
for(aY = counter = 0, maxCounter = visibleNodes.size();
counter < maxCounter; counter++) {
node = (TreeStateNode)visibleNodes.elementAt(counter);
node.setYOrigin(aY);
if(updateAll || !node.hasValidSize())
node.updatePreferredSize(counter);
aY += node.getPreferredHeight();
}
|
private void | updateYLocationsFrom(int location)Updates the y locations of all of the visible nodes after
location.
if(location >= 0 && location < getRowCount()) {
int counter, maxCounter, newYOrigin;
TreeStateNode aNode;
aNode = getNode(location);
newYOrigin = aNode.getYOrigin() + aNode.getPreferredHeight();
for(counter = location + 1, maxCounter = visibleNodes.size();
counter < maxCounter;counter++) {
aNode = (TreeStateNode)visibleNodes.
elementAt(counter);
aNode.setYOrigin(newYOrigin);
newYOrigin += aNode.getPreferredHeight();
}
}
|
private void | visibleNodesChanged()
|