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.
|