Java Institute DreamsCity 2000
Welcome to DreamsCity
Return to Java Institute

MANIPULATING HIERARCHICAL
DATA WITH JTREE

These tips were developed using Java(tm) 2 SDK, Standard Edition, 
v 1.2.2.
JTree is a Swing component used to manipulate hierarchical data such as directory/file trees. If you've worked with a file browser of any type you've probably used a tree component. You can collapse and expand the various nodes in the hierarchy. This tip will cover some basics in using JTree. A tree component consists of a root node and a set of child nodes. Each node contains a user object (like a string) and zero or more child nodes. For example, you might have a tree structure like this: testing one 1.1 two 2.1 three 3.1 3.2 3.3 The root node, testing, has three children. These child nodes have children as well. A node with no children, such as 3.2, is a leaf node. Nodes are represented by the DefaultMutableTreeNode class, which implements the interfaces TreeNode and MutableTreeNode. Mutable means that the node can change, by adding or deleting children, or by changing the user object. Here is a simple example of using JTree: import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.tree.*; import java.util.Vector; public class JTreeDemo { public static void main(String args[]) { JFrame frame = new JFrame("JTree Demo"); // handle window close frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); JPanel panel1 = new JPanel(); // set up tree root and nodes DefaultMutableTreeNode root = new DefaultMutableTreeNode("testing"); DefaultMutableTreeNode one = new DefaultMutableTreeNode("one"); one.add(new DefaultMutableTreeNode("1.1")); one.add(new DefaultMutableTreeNode("1.2")); DefaultMutableTreeNode two = new DefaultMutableTreeNode("two"); two.add(new DefaultMutableTreeNode("2.1")); two.add(new DefaultMutableTreeNode("2.2")); DefaultMutableTreeNode three = new DefaultMutableTreeNode("three"); Vector vec = new Vector(); for (int i = 1; i <= 25; i++) vec.addElement("3." + i); JTree.DynamicUtilTreeNode.createChildren(three, vec); root.add(one); root.add(two); root.add(three); // set up tree and scroller for it // also set text selection color to red JTree jt = new JTree(root); DefaultTreeCellRenderer tcr = (DefaultTreeCellRenderer)jt.getCellRenderer(); tcr.setTextSelectionColor(Color.red); JScrollPane jsp = new JScrollPane(jt); jsp.setPreferredSize(new Dimension(200, 300)); // set text field for echoing selections JPanel panel2 = new JPanel(); final JTextField tf = new JTextField(25); panel2.add(tf); // handle selections in the tree TreeSelectionListener listen; listen = new TreeSelectionListener() { public void valueChanged(TreeSelectionEvent e) { // get selected path TreePath path = e.getPath(); int cnt = path.getPathCount(); StringBuffer sb = new StringBuffer(); // pick out the path components for (int i = 0; i < cnt; i++) { String s = path.getPathComponent(i).toString(); sb.append(s); if (i + 1 != cnt) sb.append("#"); } tf.setText(sb.toString()); } }; jt.addTreeSelectionListener(listen); panel1.add(jsp); frame.getContentPane().add("North", panel1); frame.getContentPane().add("South", panel2); frame.setLocation(100, 100); frame.pack(); frame.setVisible(true); } } The node structure for the tree is constructed in a straightforward way. As nodes are created: DefaultMutableTreeNode one = new DefaultMutableTreeNode("one"); one.add(new DefaultMutableTreeNode("1.1")); one.add(new DefaultMutableTreeNode("1.2")); they are added to the parent node: root.add(one); Creating nodes one at a time, however, is tedious for large trees. So the demo illustrates an alternative. This approach uses the createChildren method of the JTree.DynamicUtilTreeNode class to create a series of nodes from a Vector object. DefaultMutableTreeNode three = new DefaultMutableTreeNode("three"); Vector vec = new Vector(); for (int i = 1; i <= 25; i++) vec.addElement("3." + i); JTree.DynamicUtilTreeNode.createChildren(three, vec); In this case, it adds 25 children to the "three" node. Once a tree is set up and displayed, how do you handle node selection in the tree? The demo shows how to set up a tree selection listener, and get and display a path. The path is a sequence of nodes from the root to the currently-selected node in the tree. A path might be: testing#three#3.7 Notice that when you select a node in the tree the path is displayed in the lower text box. There are many other aspects of JTree. For example, the class DefaultTreeCellRenderer allows you to control the way nodes are displayed. The demo above uses cell renderers, in a basic way; it specifies that the current selection should be displayed in red. But there's more that you can do with this class. For example, you can use it to specify an icon to be displayed when nodes are drawn.

Any comments? email to:
richard@dreamscity.net