Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions

  




 

 

Thinking in Java
Prev Contents / Index Next

Trees

Using a JTree can be as simple as saying:

add(new JTree(new Object[] {"this", "that", "other"}));


This displays a primitive tree. The API for trees is vast, however—certainly one of the largest in Swing. It appears that you can do just about anything with trees, but more sophisticated tasks might require quite a bit of research and experimentation.

Fortunately, there is a middle ground provided in the library: the “default” tree components, which generally do what you need. So most of the time you can use these components, and only in special cases will you need to delve in and understand trees more deeply.

The following example uses the “default” tree components to display a tree in an applet. When you press the button, a new subtree is added under the currently selected node (if no node is selected, the root node is used):

//: c14:Trees.java
// Simple Swing tree. Trees can be vastly more complex.
// <applet code=Trees width=250 height=250></applet>
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.tree.*;
import com.bruceeckel.swing.*;

// Takes an array of Strings and makes the first
// element a node and the rest leaves:
class Branch {
  private DefaultMutableTreeNode r;
  public Branch(String[] data) {
    r = new DefaultMutableTreeNode(data[0]);
    for(int i = 1; i < data.length; i++)
      r.add(new DefaultMutableTreeNode(data[i]));
  }
  public DefaultMutableTreeNode node() { return r; }
}

public class Trees extends JApplet {
  private String[][] data = {
    { "Colors", "Red", "Blue", "Green" },
    { "Flavors", "Tart", "Sweet", "Bland" },
    { "Length", "Short", "Medium", "Long" },
    { "Volume", "High", "Medium", "Low" },
    { "Temperature", "High", "Medium", "Low" },
    { "Intensity", "High", "Medium", "Low" },
  };
  private static int i = 0;
  private DefaultMutableTreeNode root, child, chosen;
  private JTree tree;
  private DefaultTreeModel model;
  public void init() {
    Container cp = getContentPane();
    root = new DefaultMutableTreeNode("root");
    tree = new JTree(root);
    // Add it and make it take care of scrolling:
    cp.add(new JScrollPane(tree), BorderLayout.CENTER);
    // Capture the tree's model:
    model =(DefaultTreeModel)tree.getModel();
    JButton test = new JButton("Press me");
    test.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        if(i < data.length) {
          child = new Branch(data[i++]).node();
          // What's the last one you clicked?
          chosen = (DefaultMutableTreeNode)
            tree.getLastSelectedPathComponent();
          if(chosen == null)
            chosen = root;
          // The model will create the appropriate event.
          // In response, the tree will update itself:
          model.insertNodeInto(child, chosen, 0);
          // Puts the new node on the chosen node.
        }
      }
    });
    // Change the button's colors:
    test.setBackground(Color.BLUE);
    test.setForeground(Color.WHITE);
    JPanel p = new JPanel();
    p.add(test);
    cp.add(p, BorderLayout.SOUTH);
  }
  public static void main(String[] args) {
    Console.run(new Trees(), 250, 250);
  }
} ///:~


The first class, Branch, is a tool to take an array of String and build a DefaultMutableTreeNode with the first String as the root and the rest of the Strings in the array as leaves. Then node( ) can be called to produce the root of this “branch.”

The Trees class contains a two-dimensional array of Strings, from which Branches can be made, and a static int i to count through this array. The DefaultMutableTreeNode objects hold the nodes, but the physical representation on screen is controlled by the JTree and its associated model, the DefaultTreeModel. Note that when the JTree is added to the applet, it is wrapped in a JScrollPane—this is all it takes to provide automatic scrolling.

The JTree is controlled through its model. When you make a change to the model, the model generates an event that causes the JTree to perform any necessary updates to the visible representation of the tree. In init( ), the model is captured by calling getModel( ). When the button is pressed, a new “branch” is created. Then the currently selected component is found (or the root is used if nothing is selected) and the model’s insertNodeInto( ) method does all the work of changing the tree and causing it to be updated.

An example like the preceding one may give you what you need in a tree. However, trees have the power to do just about anything you can imagine—everywhere you see the word “default” in the preceding example, you can substitute your own class to get different behavior. But beware: Almost all of these classes have a large interface, so you could spend a lot of time struggling to understand the intricacies of trees. Despite this, it’s a good design, and the alternatives are usually much worse.
Thinking in Java
Prev Contents / Index Next


 
 
   Reproduced courtesy of Bruce Eckel, MindView, Inc. Design by Interspire