Chapter 11 Tree Component
- In This Chapter
- Using the JTree Component
- The swing.tree Package
The JTree class is an implementation of a control that allows you to view data in a hierarchical structure. The AWT did not have a component comparable to the JTree class. Perhaps the most familiar example of a tree component in use is in a file manager type application. The file systems directory structure is organized as a tree, so the view is a natural fit.
The JTree class provides convenience methods for easy tree configuration. A tree can be configured to allow editing of the nodes in the tree. The TreeModel interface is available for creating custom data models to be viewed in the tree component. By using these techniques, the JTree class can be configured to meet almost any need for a tree component.
In this chapter, you will learn
- How to create and use the JTree class
- About the TreeModel interface
- About the TreeNode and MutableTreeNode interfaces
- How to create and use a renderer for a tree
- How to use an editor with a tree
Using the JTree Component
The visual control in the JFC for displaying hierarchical data structures is the JTree class. The tree consists of multiple nodes that can be expanded and collapsed to display more or less detail of the underlying data model. The top node in the tree is known as the root node. A node that does not contain any children nodes is known as a leaf node.
The simplest example of a JTree instance is presented in Listing 11.1. The default JTree constructor is called, and the tree is displayed. An instance of the ApplicationFrame class, presented in Chapter 8, "Frame Windows," is used to display the tree. The resulting tree after being expanded is shown in Figure 11.1.
Listing 11.1 The SimpleTreeTest Application
package com.foley.test;
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import com.foley.utility.ApplicationFrame;
/**
* An application that displays a JTree instance
* in its frame.
*
* @author Mike Foley
**/
public class SimpleTreeTest extends Object {
/**
* Application entry point.
* Create a frame and the tree and display them.
*
* @param args Command line parameter. Not used.
**/
public static void main( String args[] ) {
JFrame frame = new ApplicationFrame( "SimpleTreeTest Test" );
JTree tree = new JTree();
tree.setBorder( BorderFactory.createLoweredBevelBorder() );
frame.getContentPane().add( tree, BorderLayout.CENTER );
frame.pack();
frame.setVisible( true );
} // main
} // SimpleTreeTest
Figure 11.1 The default JTree instance.
The tree shown in Figure 11.1 uses the default tree model contained in the JTree class. The model is created in the protected getDefaultTreeModel method. JTree extensions can override this method to contain a different default model. It is seen in the figure that the root node of the tree is shown by default. Icons are associated with each node in the tree. The default icons are look-and-feel specific but tend to be of the file management type like those shown for the Metal look-and-feel in Figure 11.1. Notice that the leaf icon is different than that of non-leaf nodes. The control to the left of the icon, a dot in this figure, can be used to expand and collapse the node. This application also demonstrates that the default tree needs some data to display.
Note: Figure 11.1 shows a JTree instance when the Metal look-and-feel is being used. The horizontal lines above each node that is a child of the root node is specific to this look-and-feel. In fact, Metal defines a client property for the JTree class. When the JTree.lineStyle property is set to one of the three known valuesAngled, None, and the default Horizontalthe look-and-feel draws the lines appropriately. The property strings are case sensitive. This property is ignored in the other standard look-and-feel implementations. The Angled option, shown in Figure 11.2, is the line style familiar with most tree users.
Figure 11.2 Angled lines in the default JTree instance.
The JTree class contains versions of the constructor that take an instance of an array, Hashtable, or Vector as a parameter. You can modify the SimpleTreeTest application to create a tree instance from one of these collection classes by instantiating the JTree instance with one of the following blocks of code shown in Listing 11.2. (For the Vector and Hashtable initialization, the java.util.Vector or java.util.Hashtable package must be imported at the top of the application.) The resulting trees are shown in Figure 11.3.
Listing 11.2 Initializing a Tree from a Collection
// Test using an array.
String[] data = { "Mike", "Mari", "Molly"; };
JTree tree = new JTree( data );
// Test using a Vector.
Vector data = new Vector();
data.addElement( "Mike" );
data.addElement( "Mari" );
data.addElement( "Molly" );
JTree tree = new JTree( data );
// Test using a Hashtable.
Hashtable data = new Hashtable();
data.put( "Mike", new Integer(0) );
data.put( "Mari", new Integer(1) );
data.put( "Molly", new Integer(2) );
JTree tree = new JTree( data );
Figure 11.3 JTree initialization from the standard JDK 1.1 collections.
Figure 11.3 shows that the tree does not show the root node when initialized from a collection. You can force the root node to be displayed by passing true to the setRootVisible method. The root visibility status is a bound property in the JTree class. The complete list of bound properties introduced in the JTree class is presented in Table 11.1. The nodes in the tree created from the Hashtable are in a different order than the other two trees, and the data is not in a tree hierarchy. This is because the collection passed to the constructor does not contain hierarchical information. Having the collection contain other collections as members can rectify this situation. The following code shows this for the Vector class (see Figure 11.4), but a similar approach can be used for other collection types. The type of collection can be mixed also. For example, a vector can contain hashtables as its elements.
Vector data = new Vector();
Vector names = new Vector();
names.addElement( "Mike" );
names.addElement( "Mari" );
names.addElement( "Molly" );
data.addElement( names );
JTree tree = new JTree( data );
Table 11.1 Bound Properties Introduced in the JTree Class
|
Property Name
| Setter Method
| Getter Method
|
|
CELL_RENDERER_PROPERTY
| setCellRenderer
| getCellRenderer
|
EDITABLE_PROPERTY
| setEditable
| isEditable
|
TREE_MODEL_PROPERTY
| setModel
| getModel
|
ROOT_VISIBLE_PROPERTY
| setRootVisible
| isRootVisible
|
SHOWS_ROOT_HANDLES_PROPERTY
| setShowsRoot
| getShowsRoot
|
| Handles
| Handles
|
ROW_HEIGHT_PROPERTY
| setRowHeight
| getRowHeight
|
LARGE_MODEL_PROPERTY
| setLargeModel
| isLargeModel
|
INVOKES_STOP_CELL
| setInvokesStop
| getInvokesStop
|
_EDITING_PROPERTY
| CellEditing
| CellEditing
|
SCROLLS_ON_EXPAND_PROPERTY
| setScrollsOn
| getScrollsOn
|
| Expand
| Expand
|
SELECTION_MODEL_PROPERTY
| setSelection
| getSelection
|
| Model
| Model
|
VISIBLE_ROW_COUNT_PROPERTY
| setVisibleRow
| getVisibleRow
|
| Count
| Count
|
|
Figure 11.4 Vector-created tree.
|