All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.globalmentor.swing.tree.Trees Maven / Gradle / Ivy

The newest version!
/*
 * Copyright © 1996-2009 GlobalMentor, Inc. 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.globalmentor.swing.tree;

import javax.swing.*;
import javax.swing.tree.*;

/**
 * Utilities for working with Swing tree paths.
 * @author Garret Wilson
 */
public class Trees {

	/** This class cannot be publicly instantiated. */
	private Trees() {
	}

	/**
	 * Removes the given tree node from its parent and selects the remaining node, if the remaining node is a DefaultMutableTreeNode.
	 * @param tree The tree control that holds the model and node.
	 * @param treeModel The model from which the node should be removed.
	 * @param treeNode The node to be removed from its parent.
	 * @see #getRemainingNode
	 */
	public static void removeNodeFromParent(final JTree tree, final DefaultTreeModel treeModel, final DefaultMutableTreeNode treeNode) {
		final TreeNode remainingNode = getRemainingNode(treeNode); //see which node will remain after deletion
		treeModel.removeNodeFromParent(treeNode); //remove the node from the tree
		if(remainingNode instanceof DefaultMutableTreeNode) //if a node is remaining and it's a DefaultMutableTreeNode
			tree.setSelectionPath(new TreePath(((DefaultMutableTreeNode)remainingNode).getPath())); //select the new node
	}

	/**
	 * Returns a path representing the last path in the tree model.
	 * @param treeModel The tree model from which to construct a path.
	 * @return The path recursively composed of the last child of each child.
	 */
	public static TreePath getLastPath(final TreeModel treeModel) {
		Object object = treeModel.getRoot(); //get the root node of the tree
		TreePath path = new TreePath(object); //create a path representing just the root
		//walk the last branch of the tree until we run out of tree nodes, we
		//  find a leaf node, or we run out of child nodes
		while(object instanceof TreeNode) { //if this is a tree node
			final TreeNode treeNode = (TreeNode)object; //cast the object to a tree node
			if(!treeNode.isLeaf() && treeNode.getChildCount() > 0) { //if this isn't a leaf node and there are child nodes
				object = treeNode.getChildAt(treeNode.getChildCount() - 1); //get the last child
				path = path.pathByAddingChild(object); //add the last child to our path
			} else
				//if we find a leaf or a childless node (which should be the same condition)
				break; //stop looking for the end of the path
		}
		return path; //return the path we found
	}

	/**
	 * Finds the node that would be remaining if this node were to be deleted. This node will be the next sibling or, if there is no next sibling, the previous
	 * sibling. If there are no siblings, the parent node will be returned.
	 * 

* This method must be called before the node is removed. *

* @param treeNode The tree node that is considering deletion. * @return The node that should be selected should this node be removed, or null if there would be no node remaining. */ public static TreeNode getRemainingNode(final DefaultMutableTreeNode treeNode) { TreeNode remainingNode = treeNode.getNextSibling(); //try to get the next sibling if(remainingNode == null) { //if there is no next sibling remainingNode = treeNode.getPreviousSibling(); //try to get the previous sibling if(remainingNode == null) { //if there is no previous sibling remainingNode = treeNode.getParent(); //get the parent, whether there is one or not } } return remainingNode; //return the remaining node or null if there isn't one } /** * Finds the node that is remaining after the child at the given index was. removed. The node returned will be the node at the given index if there is such a * node, or the node at the previous index if one exists, or the parent node if the parent has no more children. *

* This method must be called after the node is removed. *

* @param parentNode The parent tree node of the child that has been deleted. * @param index The index at which the child node was located. * @return The node that should be selected after the node has been removed. */ public static TreeNode getRemainingNode(final TreeNode parentNode, final int index) { final int childCount = parentNode.getChildCount(); //find out how many nodes are left under this parent if(childCount > 0) { //if there are remaining children final int remainingIndex = Math.min(index, childCount - 1); //we'll use the child in the place of the deleted one, or the last child if that index is no longer available return parentNode.getChildAt(remainingIndex); //get the child that is in place of the deleted node, or the last node, whichever is lowest } else { //if there are no child nodes left return parentNode; //the parent node should be selected } } /** * Finds a path to the node that is remaining after the child at the given index removed. The path returned will include the node at the given index if there * is such a node, or the node at the previous index if one exists, or the parent node if the parent has no more children. *

* If the last component of the parent path is not a TreeNode, the parent path will be returned. *

*

* This method must be called after the node is removed. *

* @param parentNode The parent tree node of the child that has been deleted. * @param index The index at which the child node was located. * @return The node that should be selected after the node has been removed. * @see TreeModelEvent#getChildIndices * @see TreeModelEvent#getChildren * @see TreeModelEvent#getTreePath * @see #getRemainingNode */ public static TreePath getRemainingPath(final TreePath parentPath, final int index) { final Object parentNode = parentPath.getLastPathComponent(); //get the last path component if(parentNode instanceof TreeNode) { //if the parent is a tree node final TreeNode parentTreeNode = (TreeNode)parentNode; //cast the parent node to a tree node final TreeNode remainingNode = getRemainingNode(parentTreeNode, index); //find out which node would be remaining //if the parent node was returned, use the parent path we already have //if a child was returned, create a path by adding the child to the parent return remainingNode == parentTreeNode ? parentPath : parentPath.pathByAddingChild(remainingNode); } else { //if the parent isn't a tree node return parentPath; //just return the parent path---we can't access the children of the non-tree node parent } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy