- The Tree Control
- Tree Appearance
- The TreeNode Interface
- The MutableTreeNode Interface
- The DefaultMutableTreeNode Class
- The TreePath Class
- What is a Leaf?
- Tree Expansion and Traversal
- Expanding and Collapsing Nodes under Program Control
- Tree Expansion Events
- Making Nodes Visible
- Controlling Node Expansion and Collapse
- Tree Model Events
- Implementation Plan for the File System Control
- File System Tree Control Implementation
- Using the File System Tree Control
- Custom Tree Rendering and Editing
- Customizing the Default Tree Cell Renderer
- ToolTips and Renderers
- Custom Cell Editors
- Controlling Which Nodes Can Be Edited
- Controlling Editability by Subclassing JTree
- Programmatic Control of Editors
- Editing Trees with Custom User Objects
- The valueForPathChanged Method
- The Tree Implementation
- The Cell Editor
- The Cell Renderer
- Summary
The TreeNode Interface
Whether or not you explicitly supply the model, you will need to create the root node and attach to it all the data for the tree. All nodes are based on the TreeNode interface, which has seven methods:
public Enumeration children() public boolean getAllowsChildren() public TreeNode getChildAt(int index) public int getChildCount() public int getIndex(TreeNode child) public TreeNode getParent() public boolean isLeaf()
With the exception of isLeaf, all of these methods are concerned with the relationship between a node and its parent and children. Every node (apart from the root node) has exactly one parent and may have any number of children. If the node is a leaf node, it doesn't have children. It is also possible to have a type of node that shouldn't be considered to be a leaf when the tree draws its on-screen representation, but still doesn't allow child nodes to be connected to it. Nodes with this property return false to the getAl-lowsChildren, as should any node that can only be a leaf (such as a node representing a file in a file system). Child nodes are ordered within their parent, because the ordering might be important to the data that is being represented. Because of this property, it is possible to get the TreeNode object for a child at a given index within the parent's collection (using getChildAt) or the index for a particular child node (from getIndex). The getParent method returns a node's parent node. In the case of the root node, this returns null. Finally, getChildCount returns the number of children directly connected to a node. This value does not include grandchildren and more distant descendants.
As you can see, TreeNode is a read-only interface. To make changes to a node or its position in the tree, you need an instance of MutableTreeNode, an interface that extends TreeNode. Usually, the nodes that you actually create will be instances of DefaultMutableTreeNode, which is the Swing class implementing MutableTreeNode, so that it is usually possible to get a writable reference to any node even if you're only given a TreeNode reference by casting this reference to a MutableTreeNode. If you don't have prior knowledge of the type of node you are dealing with (perhaps because you're writing code to drive a third-party tree-based component), you should check that your TreeNode is an instance of MutableTreeNode before doing this.