banner

JTrees

Optional Reading

We will be using the Creating a GUI with JFC/Swing tutorial from Sun as a Reference source. You are not required to read the entire tutorial, I suggest you skim through it though to use a a supplement to what I give you here.

JTree

JTree is potentially even more complex than the JList. Unlike the JList, I'm not going to show you everything you can do with a JTree. Why? Because I'm sure you are already overwhelmed with this week's content.

What I do want you to get from this section is that JTree's are a powerful way of accessing a lot of hierarchical information. You can do the obvious and just display it, or you can use the JTree as a kind of advanced control to either load data in another panel or even control the internals of a CardLayout.

Making a JTree is a matter of building up a set of JTree nodes. Typically you would use a class called DefaultMutableTreeNode to build the root and then nodes/leafs of the tree.

One interesting trait to note is that the DefaultMutableTreeNode holds the "data" as a "user object". This separates the class maintaining the structure of the tree from the data itself. (This is a good thing!).

So, to build a tree we would do the following. First create your nodes:

DefaultMutableTreeNode root = new DefaultMutableTreeNode("Vacations Spots");

DefaultMutableTreeNode state1 = new DefaultMutableTreeNode("Wyoming");
DefaultMutableTreeNode state2 = new DefaultMutableTreeNode("Arizona");


DefaultMutableTreeNode state3 = new DefaultMutableTreeNode("Montana");


DefaultMutableTreeNode locationA = new DefaultMutableTreeNode("Grand Tetons");


DefaultMutableTreeNode locationB = new DefaultMutableTreeNode("Yellowstone");


DefaultMutableTreeNode locationC = new DefaultMutableTreeNode("Grand Canyon");


DefaultMutableTreeNode locationD = new DefaultMutableTreeNode("Beartooth Wilderness");

then connect the nodes

root.add(state1);
root.add(state2);
root.add(state3);
state1.add(locationA);
state1.add(locationB);
state2.add(locationC);
state3.add(locationD);

And finally add this data structure to a JTree

JTree tree = new JTree(root);

Download and open the Netbeans project simplejtree. When you run the application, you'll see the basic JTree below. Note that when the tree first comes up, only the first set of nodes are displayed.

JTree

It is possible to replace the icons with something besides the folder/paper icon scheme that comes as the default. Remember when we made our custom renderer for JList? The same idea applies. Just extend the DefaultTreeCellRenderer and call the following methods

setOpenIcon()
setClosedIcon()
setLeafIcon()

This would let you assign a single icon to all leafs, or you set a leaf to each node based on the object that node contains.

Building JTrees on the fly

If you are showing a large amount of data in a JTree, it is most likely that you don't need to build the entire tree when your application first starts up. Why? Because this uses a lot of time/cpu/memory and in all odds, the user is not going to exhaustively browse through your tree.

Instead, you can build nodes as the user goes down that particular path. The way to do this is to use a listener. There are two listeners that watch for tree node "expansion" events: TreeExpansionListener and TreeWillExpandListener. The second listener is the one we want because the first tells you a node has already expanded, but the second happens before a node expands.

If you implement a TreeWillExpandListener, you can build the next set of nodes immediately before the tree node expands.

   public void treeWillExpand(TreeExpansionEvent evt) {
TreePath path = evt.getPath();
Object obj = path.getLastPathComponent();
DefaultMutableTreeNode node = (DefaultMutableTreeNode)obj;
Integer myInt = (Integer)(node.getUserObject());
for (int i=0;i<myInt.intValue();i++) {
node.add(new ExpansionNode(new Integer(i + 1)));
}
((DefaultTreeModel)tree.getModel()).nodeStructureChanged(node);
}

Download and open the Netbeans project treeexpansion. When you run the app, you'll see a tree that has numbered nodes, and will expand the nodes by the "number" of the node you are visiting.

Dynamic JTree

There is a great deal more you can do with JTrees. But this is enough for now.



 


 

r>