Listing 16.1 JTree Displaying Its Nodes and Leaves (TJTree.java) // Demonstrates how to create the Swing tree widget to // represent hierarchical data. /* * <Applet code = TJTree width = 350 height = 300> * </Applet> */ import javax.swing.*; import javax.swing.tree.*; import java.awt.*; import java.awt.event.*; public class TJTree extends JApplet { Container container; public void init() { // 1. Get the handle on applet's content pane. container = this.getContentPane(); // 2. Root node (col0 or root) of the tree. DefaultMutableTreeNode root = new DefaultMutableTreeNode("C:\\"); // 3. Create the nodes in column 1. DefaultMutableTreeNode col11 = new DefaultMutableTreeNode("Docs"); DefaultMutableTreeNode col12 = new DefaultMutableTreeNode("README"); // 4. Add the nodes to the root. root.add(col11); root.add(col12); // 5. Create the nodes in column 2. DefaultMutableTreeNode col21 = new DefaultMutableTreeNode("API"); DefaultMutableTreeNode col22 = new DefaultMutableTreeNode("index.html"); // 6. Add the nodes to the node 1 in column 1. col11.add(col21); col11.add(col22); // 7. Create the nodes in column 3. DefaultMutableTreeNode col31 = new DefaultMutableTreeNode("Swing"); // 8. Add the node to the node 2 in column 2. col21.add(col31); // 9. Create the nodes in column 4. DefaultMutableTreeNode col41 = new DefaultMutableTreeNode("JComponent.html"); DefaultMutableTreeNode col42 = new DefaultMutableTreeNode("JButton.html"); DefaultMutableTreeNode col43 = new DefaultMutableTreeNode("JLabel.html"); // 10. Add the nodes to the node called Swing. col31.add(col41); col31.add(col42); col31.add(col43); // 11. Attach the root (of nodes) to the tree object. JTree tree = new JTree(root); // 12. Add the tree to a scroll pane and add the scroll pane // to the container. JScrollPane scrollPane = new JScrollPane(tree); container.add(scrollPane); } } Listing 16.2 JTree Displaying the File System Hierarchy Using the Custom Tree Model (TTreeModel.java) // Demonstrates how to use custom data models in trees. import javax.swing.*; import javax.swing.tree.*; import javax.swing.event.*; import java.awt.*; import java.awt.event.*; import java.io.File; import java.util.*; public class TTreeModel extends JFrame { public TTreeModel() { super("TTreeModel"); // Give a title to the frame // 1. Create an object of FileSystemModel, and create a tree // with that model. Add the tree to a scroll pane, and add // the scroll pane to the frame. FileSystemModel fileSystemDataModel = new FileSystemModel(); JTree tree = new JTree(fileSystemDataModel); JScrollPane scrollPane = new JScrollPane(tree); getContentPane().add(scrollPane); // 2. Configure the frame and display it. addWindowListener(new WindowEventHandler()); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); setSize(300, 250); show(); } // 3. The main method. public static void main(String [] args) { TTreeModel frame = new TTreeModel(); } // 4. Define a listener class to close the frame. class WindowEventHandler extends WindowAdapter { public void windowClosing(WindowEvent evt) { System.exit(0); } } } // 5. Custom data model that represents the file system data. class FileSystemModel implements TreeModel { private String root; // The root identifier private Vector listeners; // Declare the listeners vector public FileSystemModel() { // 6. Get the home directory on your system. root = System.getProperty("user.home"); // 7. For Windows 95, root is set to C:\ ("usr.home" // retrieves C:\WIN95). // You may implement a snippet like this for other OS also // like Windows NT, Macintosh, and so on. if (System.getProperty("os.name").equals("Windows 95")) { File tempFile = new File(root); root = tempFile.getParent(); } // 8. Define the listeners vector. listeners = new Vector(); } // 9. Retrieves the root of the tree hierarchy. public Object getRoot() { return (new File(root)); } // 10. Retrieves the members in a directory based on an index. public Object getChild(Object parent, int index) { File directory = (File) parent; String[] directoryMembers = directory.list(); return (new File(directory, directoryMembers[index])); } // 11. Retrieves the member count in a directory. public int getChildCount(Object parent) { File fileSystemMember = (File) parent; // fileSystemMember is a directory or file. // If a file system member is a directory. if (fileSystemMember.isDirectory()) { String[] directoryMembers = fileSystemMember.list(); // Get the count of members in the directory. return directoryMembers.length; } // If the file system member is a file. else { // Return the member count as zero. return 0; } } // 12. Returns the index of a given member in its directory. public int getIndexOfChild(Object parent, Object child) { File directory = (File) parent; File directoryMember = (File) child; String[] directoryMemberNames = directory.list(); int result = -1; for (int i = 0; i<directoryMemberNames.length; ++i) { if ( directoryMember.getName().equals( directoryMemberNames[i] ) ) { result = i; break; } } // If no member with such name in the directory. return result; } // 13. Indicates whether a directory member is a tree leaf. public boolean isLeaf(Object node) { return ((File) node).isFile(); } // 14. Method to add a tree model listener. public void addTreeModelListener(TreeModelListener l) { if (l != null && !listeners.contains(l)) { listeners.addElement(l); } } // 15. Method to remove a tree model listener. public void removeTreeModelListener(TreeModelListener l) { if (l != null) { listeners.removeElement(l); } } // A dumb method. public void valueForPathChanged(TreePath path, Object newValue) { // Does Nothing! } // 16. Additional methods that fire events whenever the model is // subjected to change. Possible changes can be nodes // inserted, nodes removed, structure changed, and so on. public void fireTreeNodesInserted(TreeModelEvent e) { Enumeration listenerCount = listeners.elements(); while (listenerCount.hasMoreElements()) { TreeModelListener listener = (TreeModelListener) listenerCount.nextElement(); listener.treeNodesInserted(e); } } public void fireTreeNodesRemoved(TreeModelEvent e) { Enumeration listenerCount = listeners.elements(); while (listenerCount.hasMoreElements()) { TreeModelListener listener = (TreeModelListener) listenerCount.nextElement(); listener.treeNodesRemoved(e); } } public void fireTreeNodesChanged(TreeModelEvent e) { Enumeration listenerCount = listeners.elements(); while (listenerCount.hasMoreElements()) { TreeModelListener listener = (TreeModelListener) listenerCount.nextElement(); listener.treeNodesChanged(e); } } public void fireTreeStructureChanged(TreeModelEvent e) { Enumeration listenerCount = listeners.elements(); while (listenerCount.hasMoreElements()) { TreeModelListener listener = (TreeModelListener) listenerCount.nextElement(); listener.treeStructureChanged(e); } } } Listing 16.3 JTree Node Selections to Display a Document in an Editor Pane (TTreeSelectionEvent.java) // Demonstrates the tree selection events and listeners. import javax.swing.*;import javax.swing.tree.*;import javax.swing.event.*; import java.awt.*; import java.awt.event.*; import java.net.*; import java.io.*; public class TTreeSelectionEvent extends JFrame { Container container; DefaultMutableTreeNode root; JScrollPane treeScrollPane; JScrollPane editorScrollPane; JEditorPane editorPane; public TTreeSelectionEvent() { // 1. Get the handle on applet's content pane and // create the tree nodes super("TTreeSelectionEvent"); container = this.getContentPane(); createTreeNodes(); // 2. Attach the root of the nodes to the tree object // and set the tree to the SINGLE SELECTION mode. // Also, register a tree selection listener with the // tree object to listen to the respective events fired. JTree tree = new JTree(root); tree.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION); tree.addTreeSelectionListener(new SelectionListener()); // 3. Create scroll panes to display the tree, and the // editor component. Add the scroll panes to a split pane. // Add the split pane to the applet treeScrollPane = new JScrollPane(tree); editorPane = new JEditorPane(); editorScrollPane = new JScrollPane(editorPane); JSplitPane splitPane = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT, true, // Continuous Layout treeScrollPane, editorScrollPane); // 4. Add the split pane to the frame. container.add(splitPane); // 5. Add the window closing listener. addWindowListener(new WindowEventHandler()); // 6. Configure the frame. setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); setSize(350, 250); show(); } // 7. Method that creates the tree nodes. public void createTreeNodes() { // 8. Root node (col0 (col-zero) or root) of the tree. root = new DefaultMutableTreeNode("C:\\"); // 9. Create the nodes in column 1. // and add them to the root DefaultMutableTreeNode col11 = new DefaultMutableTreeNode("JavaProg"); root.add(col11); // 10. Create the nodes in column 2. DefaultMutableTreeNode col21 = new DefaultMutableTreeNode("Swing"); // 11. Add the node to the node 2 in column 2. col11.add(col21); // 12. Create the nodes in column 3. DefaultMutableTreeNode col31 = new DefaultMutableTreeNode("JComponent.html"); DefaultMutableTreeNode col32 = new DefaultMutableTreeNode("JButton.html"); DefaultMutableTreeNode col33 = new DefaultMutableTreeNode("JLabel.html"); // 13. Add the nodes to the node called Swing. col21.add(col31); col21.add(col32); col21.add(col33); } // 14. Define the tree selection listener. class SelectionListener implements TreeSelectionListener { URL url; // 15. Method that needs to be implemented. public void valueChanged(TreeSelectionEvent se) { // Obtain the source. JTree tree = (JTree) se.getSource(); // Obtain the selected node. DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); // Obtain the selected node name. String selectedNodeName = selectedNode.toString(); // If the node is a leaf, obtain its URL string. if (selectedNode.isLeaf()) { String urlString = "file:" + System.getProperty("user.dir") + System.getProperty("file.separator") + selectedNodeName; System.out.println(urlString); try { // Create URL object. url = new URL(urlString); } catch(MalformedURLException urlex) { System.out.println(�Marlformed URL Exception.�); } try { // Display the resource at the specified URL. editorPane.setPage(url); } catch(IOException ex) { System.out.println("The selected file was not found."); System.out.println(ex); } } } } // 16. Event handler for window closing. class WindowEventHandler extends WindowAdapter { public void windowClosing(WindowEvent evt) { System.exit(0); } } // 17. The main method. public static void main(String[] args) { TTreeSelectionEvent frame = new TTreeSelectionEvent(); } } Listing 16.4 DefaultTreeCellRenderer Example (TTreeCellRenderer.java) // Demonstrates how to customize the display of // the tree nodes (or leaves). /* * <Applet code = TTreeCellRenderer width = 350 height = 300> * </Applet> */ import javax.swing.*; import javax.swing.tree.*; import java.awt.*; import java.awt.event.*; public class TTreeCellRenderer extends JApplet { Container container; public void init() { // 1. Get the handle on applet's content pane. container = this.getContentPane(); // 2. Root node (col0 or root) of the tree. DefaultMutableTreeNode root = new DefaultMutableTreeNode("C:\\"); // 3. Create the nodes in column 1. DefaultMutableTreeNode col11 = new DefaultMutableTreeNode("Docs"); DefaultMutableTreeNode col12 = new DefaultMutableTreeNode("Others"); // 4. Add the nodes to the root. root.add(col11); root.add(col12); // 5. Create the nodes in column 2. DefaultMutableTreeNode col21 = new DefaultMutableTreeNode("API"); DefaultMutableTreeNode col22 = new DefaultMutableTreeNode("Bla..."); // 6. Add these nodes to node 1 in column 1. col11.add(col21); col12.add(col22); // 7. Create the nodes in column 3. DefaultMutableTreeNode col31 = new DefaultMutableTreeNode("Swing"); // 8. Add the node to node 2 in column 2. col21.add(col31); // 9. Create the nodes in column 4. DefaultMutableTreeNode col41 = new DefaultMutableTreeNode("JComponent.html"); DefaultMutableTreeNode col42 = new DefaultMutableTreeNode("JButton.html"); DefaultMutableTreeNode col43 = new DefaultMutableTreeNode("JLabel.html"); // 10. Add the nodes to the node called Swing. col31.add(col41); col31.add(col42); col31.add(col43); // 11. Attach the root (of nodes) to the tree object. JTree tree = new JTree(root); // 12. Get the reference to the existing (default) renderer. DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) tree.getCellRenderer(); // 13. Prepare the cell height for the new icons. tree.setRowHeight(30); // 30 pixels // 14. Attach the new icons for the leaves nodes when opened, // and nodes when closed. renderer.setLeafIcon(new ImageIcon("leafIcon.gif")); renderer.setOpenIcon(new ImageIcon("fileOpen.gif")); renderer.setClosedIcon(new ImageIcon("fileClosed.gif")); // 15. Customize the text colors. renderer.setFont(new Font("Monospaced", // font name Font.BOLD|Font.ITALIC, // font type 15)); // Font size. renderer.setTextNonSelectionColor(Color.blue); renderer.setTextSelectionColor(Color.white); // 16. Customize the background of the tree node-cells. renderer.setBackgroundNonSelectionColor(Color.white); renderer.setBackgroundSelectionColor(Color.gray); renderer.setBorderSelectionColor(Color.lightGray); // 17. Finally, add the tree to a scroll pane and the scroll pane // to the container. JScrollPane scrollPane = new JScrollPane(tree); container.add(scrollPane); } }