Java Tutorial/Swing/JTree Node

Материал из Java эксперт
Перейти к: навигация, поиск

Adding a Node to a JTree Component

   <source lang="java">

import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.MutableTreeNode; import javax.swing.tree.TreePath; public class Main {

 public static void main(String[] argv) throws Exception {
   JTree tree = new JTree();
   DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
   TreePath path = tree.getSelectionPath();
   MutableTreeNode node = (MutableTreeNode) path.getLastPathComponent();
   MutableTreeNode newNode = new DefaultMutableTreeNode("green");
   model.insertNodeInto(newNode, node, node.getChildCount());
 }

}</source>





A JTree subclass that displays the tree of AWT or Swing component that make up a GUI

   <source lang="java">

/*

* Copyright (c) 2004 David Flanagan.  All rights reserved.
* This code is from the book Java Examples in a Nutshell, 3nd Edition.
* It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.
* You may study, use, and modify it for any non-commercial purpose,
* including teaching and use in open-source projects.
* You may distribute it non-commercially as long as you retain this notice.
* For a commercial use license, or to purchase the book, 
* please visit http://www.davidflanagan.ru/javaexamples3.
*/

import java.awt.BorderLayout; import java.awt.ruponent; import java.awt.Container; import java.awt.Font; import java.awt.Point; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.event.TreeModelListener; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.TreeCellRenderer; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; /**

* This class is a JTree subclass that displays the tree of AWT or Swing
* component that make up a GUI.
*/

public class ComponentTree extends JTree {

 /**
  * All this constructor method has to do is set the TreeModel and
  * TreeCellRenderer objects for the tree. It is these classes (defined below)
  * that do all the real work.
  */
 public ComponentTree(Component c) {
   super(new ComponentTreeModel(c));
   setCellRenderer(new ComponentCellRenderer(getCellRenderer()));
 }
 /**
  * The TreeModel class puts hierarchical data in a form that the JTree can
  * display. This implementation interprets the containment hierarchy of a
  * Component for display by the ComponentTree class. Note that any kind of
  * Object can be a node in the tree, as long as the TreeModel knows how to
  * handle it.
  */
 static class ComponentTreeModel implements TreeModel {
   Component root; // The root object of the tree
   // Constructor: just remember the root object
   public ComponentTreeModel(Component root) {
     this.root = root;
   }
   // Return the root of the tree
   public Object getRoot() {
     return root;
   }
   // Is this node a leaf? (Leaf nodes are displayed differently by JTree)
   // Any node that isn"t a container is a leaf, since they cannot have
   // children. We also define containers with no children as leaves.
   public boolean isLeaf(Object node) {
     if (!(node instanceof Container))
       return true;
     Container c = (Container) node;
     return c.getComponentCount() == 0;
   }
   // How many children does this node have?
   public int getChildCount(Object node) {
     if (node instanceof Container) {
       Container c = (Container) node;
       return c.getComponentCount();
     }
     return 0;
   }
   // Return the specified child of a parent node.
   public Object getChild(Object parent, int index) {
     if (parent instanceof Container) {
       Container c = (Container) parent;
       return c.getComponent(index);
     }
     return null;
   }
   // Return the index of the child node in the parent node
   public int getIndexOfChild(Object parent, Object child) {
     if (!(parent instanceof Container))
       return -1;
     Container c = (Container) parent;
     Component[] children = c.getComponents();
     if (children == null)
       return -1;
     for (int i = 0; i < children.length; i++) {
       if (children[i] == child)
         return i;
     }
     return -1;
   }
   // This method is only required for editable trees, so it is not
   // implemented here.
   public void valueForPathChanged(TreePath path, Object newvalue) {
   }
   // This TreeModel never fires any events (since it is not editable)
   // so event listener registration methods are left unimplemented
   public void addTreeModelListener(TreeModelListener l) {
   }
   public void removeTreeModelListener(TreeModelListener l) {
   }
 }
 /**
  * A TreeCellRenderer displays each node of a tree. The default renderer
  * displays arbitrary Object nodes by calling their toString() method. The
  * Component.toString() method returns long strings with extraneous
  * information. Therefore, we use this "wrapper" implementation of
  * TreeCellRenderer to convert nodes from Component objects to useful String
  * values before passing those String values on to the default renderer.
  */
 static class ComponentCellRenderer implements TreeCellRenderer {
   TreeCellRenderer renderer; // The renderer we are a wrapper for
   // Constructor: just remember the renderer
   public ComponentCellRenderer(TreeCellRenderer renderer) {
     this.renderer = renderer;
   }
   // This is the only TreeCellRenderer method.
   // Compute the string to display, and pass it to the wrapped renderer
   public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected,
       boolean expanded, boolean leaf, int row, boolean hasFocus) {
     String newvalue = value.getClass().getName(); // Component type
     String name = ((Component) value).getName(); // Component name
     if (name != null)
       newvalue += " (" + name + ")"; // unless null
     // Use the wrapped renderer object to do the real work
     return renderer.getTreeCellRendererComponent(tree, newvalue, selected, expanded, leaf, row,
         hasFocus);
   }
 }
 /**
  * This main() method demonstrates the use of the ComponentTree class: it puts
  * a ComponentTree component in a Frame, and uses the ComponentTree to display
  * its own GUI hierarchy. It also adds a TreeSelectionListener to display
  * additional information about each component as it is selected
  */
 public static void main(String[] args) {
   // Create a frame for the demo, and handle window close requests
   JFrame frame = new JFrame("ComponentTree Demo");
   frame.addWindowListener(new WindowAdapter() {
     public void windowClosing(WindowEvent e) {
       System.exit(0);
     }
   });
   // Create a scroll pane and a "message line" and add them to the
   // center and bottom of the frame.
   JScrollPane scrollpane = new JScrollPane();
   final JLabel msgline = new JLabel(" ");
   frame.getContentPane().add(scrollpane, BorderLayout.CENTER);
   frame.getContentPane().add(msgline, BorderLayout.SOUTH);
   // Now create the ComponentTree object, specifying the frame as the
   // component whose tree is to be displayed. Also set the tree"s font.
   JTree tree = new ComponentTree(frame);
   tree.setFont(new Font("SansSerif", Font.BOLD, 12));
   // Only allow a single item in the tree to be selected at once
   tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
   // Add an event listener for notifications when
   // the tree selection state changes.
   tree.addTreeSelectionListener(new TreeSelectionListener() {
     public void valueChanged(TreeSelectionEvent e) {
       // Tree selections are referred to by "path"
       // We only care about the last node in the path
       TreePath path = e.getPath();
       Component c = (Component) path.getLastPathComponent();
       // Now we know what component was selected, so
       // display some information about it in the message line
       if (c.isShowing()) {
         Point p = c.getLocationOnScreen();
         msgline.setText("x: " + p.x + "  y: " + p.y + "  width: " + c.getWidth() + "  height: "
             + c.getHeight());
       } else {
         msgline.setText("component is not showing");
       }
     }
   });
   // Now that we"ve set up the tree, add it to the scrollpane
   scrollpane.setViewportView(tree);
   // Finally, set the size of the main window, and pop it up.
   frame.setSize(600, 400);
   frame.setVisible(true);
 }

}</source>





CheckBox Tree node

   <source lang="java">

import java.awt.ruponent; import javax.swing.DefaultCellEditor; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.MutableTreeNode; import javax.swing.tree.TreePath; class TrueFalseTreeNodeData {

 protected final String value;
 protected boolean booleanValue;
 public TrueFalseTreeNodeData(String quest) {
   value = quest;
 }
 public String getQuestion() {
   return value;
 }
 public boolean getAnswer() {
   return booleanValue;
 }
 public void setAnswer(boolean ans) {
   booleanValue = ans;
 }
 public String toString() {
   return value + " = " + booleanValue;
 }

} public class TreeTest extends JFrame {

 protected final static String[] questions = { "A","B","C" };
 public static void main(String[] args) {
   TreeTest tt = new TreeTest();
   tt.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   tt.setSize(500, 200);
   tt.setVisible(true);
 }
 public TreeTest() {
   super();
   JTree tree = new JTree(getRootNode()) {
     public boolean isPathEditable(TreePath path) {
       Object comp = path.getLastPathComponent();
       if (comp instanceof DefaultMutableTreeNode) {
         DefaultMutableTreeNode node = (DefaultMutableTreeNode) comp;
         Object userObject = node.getUserObject();
         if (userObject instanceof TrueFalseTreeNodeData) {
           return true;
         }
       }
       return false;
     }
   };
   QuestionCellRenderer renderer = new QuestionCellRenderer();
   tree.setCellRenderer(renderer);
   QuestionCellEditor editor = new QuestionCellEditor();
   tree.setCellEditor(editor);
   tree.setEditable(true);
   JScrollPane jsp = new JScrollPane(tree);
   getContentPane().add(jsp);
 }
 protected MutableTreeNode getRootNode() {
   DefaultMutableTreeNode root, child;
   TrueFalseTreeNodeData question;
   root = new DefaultMutableTreeNode("Root");
   for (int i = 0; i < questions.length; i++) {
     question = new TrueFalseTreeNodeData(questions[i]);
     child = new DefaultMutableTreeNode(question);
     root.add(child);
   }
   return root;
 }

} class QuestionCellRenderer extends DefaultTreeCellRenderer {

 protected JCheckBox checkBoxRenderer = new JCheckBox();
 public Component getTreeCellRendererComponent(JTree tree, Object value,
     boolean selected, boolean expanded, boolean leaf, int row,
     boolean hasFocus) {
   if (value instanceof DefaultMutableTreeNode) {
     DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
     Object userObject = node.getUserObject();
     if (userObject instanceof TrueFalseTreeNodeData) {
       TrueFalseTreeNodeData question = (TrueFalseTreeNodeData) userObject;
       prepareQuestionRenderer(question, selected);
       return checkBoxRenderer;
     }
   }
   return super.getTreeCellRendererComponent(tree, value, selected, expanded,
       leaf, row, hasFocus);
 }
 protected void prepareQuestionRenderer(TrueFalseTreeNodeData tfq, boolean selected) {
   checkBoxRenderer.setText(tfq.getQuestion());
   checkBoxRenderer.setSelected(tfq.getAnswer());
   if (selected) {
     checkBoxRenderer.setForeground(getTextSelectionColor());
     checkBoxRenderer.setBackground(getBackgroundSelectionColor());
   } else {
     checkBoxRenderer.setForeground(getTextNonSelectionColor());
     checkBoxRenderer.setBackground(getBackgroundNonSelectionColor());
   }
 }

} class QuestionCellEditor extends DefaultCellEditor {

 protected TrueFalseTreeNodeData nodeData;
 public QuestionCellEditor() {
   super(new JCheckBox());
 }
 public Component getTreeCellEditorComponent(JTree tree, Object value,
     boolean selected, boolean expanded, boolean leaf, int row) {
   JCheckBox editor = null;
   nodeData = getQuestionFromValue(value);
   if (nodeData != null) {
     editor = (JCheckBox) (super.getComponent());
     editor.setText(nodeData.getQuestion());
     editor.setSelected(nodeData.getAnswer());
   }
   return editor;
 }
 public static TrueFalseTreeNodeData getQuestionFromValue(Object value) {
   if (value instanceof DefaultMutableTreeNode) {
     DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
     Object userObject = node.getUserObject();
     if (userObject instanceof TrueFalseTreeNodeData) {
       return (TrueFalseTreeNodeData) userObject;
     }
   }
   return null;
 }
 public Object getCellEditorValue() {
   JCheckBox editor = (JCheckBox) (super.getComponent());
   nodeData.setAnswer(editor.isSelected());
   return nodeData;
 }

}</source>





Converting All Nodes in a JTree Component to a TreePath Array

   <source lang="java">

import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import javax.swing.JTree; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; public class Main {

 public TreePath[] getPaths(JTree tree, boolean expanded) {
   TreeNode root = (TreeNode) tree.getModel().getRoot();
   List<TreePath> list = new ArrayList<TreePath>();
   getPaths(tree, new TreePath(root), expanded, list);
   return (TreePath[]) list.toArray(new TreePath[list.size()]);
 }
 public void getPaths(JTree tree, TreePath parent, boolean expanded, List<TreePath> list) {
   if (expanded && !tree.isVisible(parent)) {
     return;
   }
   list.add(parent);
   TreeNode node = (TreeNode) parent.getLastPathComponent();
   if (node.getChildCount() >= 0) {
     for (Enumeration e = node.children(); e.hasMoreElements();) {
       TreeNode n = (TreeNode) e.nextElement();
       TreePath path = parent.pathByAddingChild(n);
       getPaths(tree, path, expanded, list);
     }
   }
 }

}</source>





Delete tree node

   <source lang="java">

import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.InputEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.JFrame; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreePath; public class DeleteNodes extends JFrame {

 protected JTree tree;
 public static void main(String[] args) {
   DeleteNodes dn = new DeleteNodes(new JTree());
   dn.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   dn.setSize(400, 300);
   dn.setVisible(true);
 }
 public DeleteNodes(JTree jt) {
   super();
   tree = jt;
   getContentPane().add(tree);
   tree.addMouseListener(new MouseAdapter() {
     public void mousePressed(MouseEvent event) {
       if (((event.getModifiers() & InputEvent.BUTTON3_MASK) != 0)
           && (tree.getSelectionCount() > 0)) {
         showMenu(event.getX(), event.getY());
       }
     }
   });
 }
 protected void showMenu(int x, int y) {
   JPopupMenu popup = new JPopupMenu();
   JMenuItem mi = new JMenuItem("Delete");
   TreePath path = tree.getSelectionPath();
   Object node = path.getLastPathComponent();
   if (node == tree.getModel().getRoot()) {
     mi.setEnabled(false);
   }
   popup.add(mi);
   mi.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent event) {
       deleteSelectedItems();
     }
   });
   popup.show(tree, x, y);
 }
 protected void deleteSelectedItems() {
   DefaultMutableTreeNode node;
   DefaultTreeModel model = (DefaultTreeModel) (tree.getModel());
   TreePath[] paths = tree.getSelectionPaths();
   for (int i = 0; i < paths.length; i++) {
     node = (DefaultMutableTreeNode) (paths[i].getLastPathComponent());
     model.removeNodeFromParent(node);
   }
 }

}</source>





Expanding or Collapsing All Nodes in a JTree Component

   <source lang="java">

import java.util.Enumeration; import javax.swing.JTree; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; public class Main {

 public void expandAll(JTree tree) {
   TreeNode root = (TreeNode) tree.getModel().getRoot();
   expandAll(tree, new TreePath(root));
 }
 private void expandAll(JTree tree, TreePath parent) {
   TreeNode node = (TreeNode) parent.getLastPathComponent();
   if (node.getChildCount() >= 0) {
     for (Enumeration e = node.children(); e.hasMoreElements();) {
       TreeNode n = (TreeNode) e.nextElement();
       TreePath path = parent.pathByAddingChild(n);
       expandAll(tree, path);
     }
   }
   tree.expandPath(parent);
   // tree.collapsePath(parent);
 }

}</source>





Expression Tree

   <source lang="java">

import java.util.Enumeration; import java.util.Stack; import javax.swing.JFrame; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; public class ExpressionTree extends JFrame {

 public ExpressionTree() {
   setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   DefaultMutableTreeNode root = new DefaultMutableTreeNode("+");
   root.add(new DefaultMutableTreeNode(new Integer(3)));
   DefaultMutableTreeNode node = new DefaultMutableTreeNode("*");
   node.add(new DefaultMutableTreeNode(new Integer(4)));
   node.add(new DefaultMutableTreeNode(new Integer(5)));
   root.add(node);
   JTree tree = new JTree(root);
   getContentPane().add(tree);
   pack();
   setVisible(true);
   Stack stack = new Stack(); 
   Enumeration e = root.postorderEnumeration();
   while (e.hasMoreElements()) { 
     DefaultMutableTreeNode node1 = (DefaultMutableTreeNode) (e.nextElement());
     Object obj = node1.getUserObject();
     if (obj instanceof Integer) {
       stack.push(obj);
     } else {
       String operator = (String) obj;
       Integer v1 = (Integer) stack.pop();
       Integer v2 = (Integer) stack.pop();
       if (operator.equals("+")) {
         stack.push(new Integer(v2.intValue() + v1.intValue()));
       } else {
         stack.push(new Integer(v2.intValue() * v1.intValue()));
       }
     }
   }
   System.out.println(stack.pop());
 }
 public static void main(String[] args) {
   ExpressionTree t = new ExpressionTree();
 }

}</source>





Get child count, depth, leaf count

   <source lang="java">

import javax.swing.JFrame; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; public class MainClass extends JFrame {

 public MainClass() {
   setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   DefaultMutableTreeNode root = new DefaultMutableTreeNode("+");
   root.add(new DefaultMutableTreeNode(new Integer(3)));
   DefaultMutableTreeNode node = new DefaultMutableTreeNode("*");
   node.add(new DefaultMutableTreeNode(new Integer(4)));
   node.add(new DefaultMutableTreeNode(new Integer(5)));
   root.add(node);
   JTree tree = new JTree(root);
   getContentPane().add(tree);
   pack();
   setVisible(true);
   System.out.println("The root has " + root.getChildCount() + " children");
   System.out.println("The tree"s depth is " + root.getDepth());
   System.out.println("The tree has " + root.getLeafCount() + " leaves");
   System.out.println(""Root" is really a root? " + root.isRoot());
   System.out.println("Root"s userObject: " + root.toString());
 }
 public static void main(String[] args) {
   MainClass t = new MainClass();
 }

}</source>





Get path for all expanded or not expanded tree pathes

   <source lang="java">

import java.util.Enumeration; import java.util.List; import javax.swing.JTree; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; public class Main {

 public void getPaths(JTree tree, TreePath parent, boolean expanded, List<TreePath> list) {
   if (expanded && !tree.isVisible(parent)) {
     return;
   }
   list.add(parent);
   TreeNode node = (TreeNode) parent.getLastPathComponent();
   if (node.getChildCount() >= 0) {
     for (Enumeration e = node.children(); e.hasMoreElements();) {
       TreeNode n = (TreeNode) e.nextElement();
       TreePath path = parent.pathByAddingChild(n);
       getPaths(tree, path, expanded, list);
     }
   }
 }

}</source>





JTree node mouse click event

   <source lang="java">

import java.awt.BorderLayout; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.JTree; import javax.swing.ScrollPaneConstants; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreePath; public class MainClass {

 public static void main(String[] a) {
   JFrame f = new JFrame();
   f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   f.add(new JTreeEvents());
   f.setSize(500, 500);
   f.setVisible(true);
 }

} class JTreeEvents extends JPanel {

 JTree tree;
 JTextField jtf;
 public JTreeEvents() {
   setLayout(new BorderLayout());
   DefaultMutableTreeNode top = new DefaultMutableTreeNode("Options");
   DefaultMutableTreeNode a = new DefaultMutableTreeNode("A");
   top.add(a);
   
   a.add(new DefaultMutableTreeNode("A1"));
   a.add(new DefaultMutableTreeNode("A2"));
   DefaultMutableTreeNode b = new DefaultMutableTreeNode("B");
   top.add(b);
   
   b.add(new DefaultMutableTreeNode("B1"));
   b.add(new DefaultMutableTreeNode("B2"));
   b.add(new DefaultMutableTreeNode("B3"));
   tree = new JTree(top);
   int v = ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED;
   int h = ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED;
   JScrollPane jsp = new JScrollPane(tree, v, h);
   add(jsp, BorderLayout.CENTER);
   jtf = new JTextField("", 20);
   add(jtf, BorderLayout.SOUTH);
   tree.addMouseListener(new MouseAdapter() {
     public void mouseClicked(MouseEvent me) {
       doMouseClicked(me);
     }
   });
 }
 void doMouseClicked(MouseEvent me) {
   TreePath tp = tree.getPathForLocation(me.getX(), me.getY());
   if (tp != null)
     jtf.setText(tp.toString());
   else
     jtf.setText("");
 }

}</source>





JTree root cannot be removed with removeNodeFromParent(), use DefaultTreeModel.setRoot() to remove the root

   <source lang="java">

import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.tree.DefaultTreeModel; public class TreeRootRemove {

 public static void main(String[] argv) {
   JTree tree = new JTree();
   DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
   model.setRoot(null);
   JFrame frame = new JFrame();
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.add(new JScrollPane(tree));
   frame.setSize(380, 320);
   frame.setLocationRelativeTo(null);
   frame.setVisible(true);
 }

}</source>





Removing a Node to a JTree Component

   <source lang="java">

import javax.swing.JTree; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.MutableTreeNode; import javax.swing.tree.TreePath; public class Main {

 public static void main(String[] argv) throws Exception {
   JTree tree = new JTree();
   DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
   TreePath path = tree.getSelectionPath();
   MutableTreeNode node = (MutableTreeNode) path.getLastPathComponent();
   model.removeNodeFromParent(node);
   model.setRoot(null);
 }

}</source>





Searching node in a JTree

   <source lang="java">

import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Enumeration; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.MutableTreeNode; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; public class EditableTree extends JFrame {

 private DefaultMutableTreeNode m_rootNode = new DefaultMutableTreeNode("AA");
 private DefaultTreeModel m_model = new DefaultTreeModel(m_rootNode);
 private JTree m_tree = new JTree(m_model);
 private JButton m_addButton = new JButton("Add Node");
 private JButton m_delButton = new JButton("Delete Node");
 private JButton m_searchButton = new JButton("Search Node");
 private JButton m_searchAndDeleteButton = new JButton("Search and Delete Node");
 private JTextField m_searchText;
 public EditableTree() {
   DefaultMutableTreeNode forums = new DefaultMutableTreeNode("A");
   forums.add(new DefaultMutableTreeNode("B"));
   DefaultMutableTreeNode articles = new DefaultMutableTreeNode("E");
   articles.add(new DefaultMutableTreeNode("F"));
   DefaultMutableTreeNode examples = new DefaultMutableTreeNode("G");
   examples.add(new DefaultMutableTreeNode("H"));
   m_rootNode.add(forums);
   m_rootNode.add(articles);
   m_rootNode.add(examples);
   m_tree.setEditable(true);
   m_tree.setSelectionRow(0);
   JScrollPane scrollPane = new JScrollPane(m_tree);
   getContentPane().add(scrollPane, BorderLayout.CENTER);
   JPanel panel = new JPanel();
   m_addButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {
       DefaultMutableTreeNode selNode = (DefaultMutableTreeNode) m_tree
           .getLastSelectedPathComponent();
       if (selNode == null) {
         return;
       }
       DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("New Node");
       m_model.insertNodeInto(newNode, selNode, selNode.getChildCount());
       TreeNode[] nodes = m_model.getPathToRoot(newNode);
       TreePath path = new TreePath(nodes);
       m_tree.scrollPathToVisible(path);
       m_tree.setSelectionPath(path);
       m_tree.startEditingAtPath(path);
     }
   });
   panel.add(m_addButton);
   m_delButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {
       DefaultMutableTreeNode selNode = (DefaultMutableTreeNode) m_tree
           .getLastSelectedPathComponent();
       removeNode(selNode);
     }
   });
   panel.add(m_delButton);
   JPanel searchPanel = new JPanel();
   searchPanel.setBorder(BorderFactory.createEtchedBorder());
   m_searchText = new JTextField(10);
   searchPanel.add(m_searchText);
   m_searchButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {
       DefaultMutableTreeNode node = searchNode(m_searchText.getText());
       if (node != null) {
         TreeNode[] nodes = m_model.getPathToRoot(node);
         TreePath path = new TreePath(nodes);
         m_tree.scrollPathToVisible(path);
         m_tree.setSelectionPath(path);
       } else {
         System.out.println("Node with string " + m_searchText.getText() + " not found");
       }
     }
   });
   searchPanel.add(m_searchButton);
   m_searchAndDeleteButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {
       DefaultMutableTreeNode node = searchNode(m_searchText.getText());
       if (node != null) {
         removeNode(node);
       } else {
         System.out.println("Node with string " + m_searchText.getText() + " not found");
       }
     }
   });
   searchPanel.add(m_searchAndDeleteButton);
   panel.add(searchPanel);
   getContentPane().add(panel, BorderLayout.SOUTH);
   setSize(700, 400);
   setVisible(true);
 }
 public DefaultMutableTreeNode searchNode(String nodeStr) {
   DefaultMutableTreeNode node = null;
   Enumeration e = m_rootNode.breadthFirstEnumeration();
   while (e.hasMoreElements()) {
     node = (DefaultMutableTreeNode) e.nextElement();
     if (nodeStr.equals(node.getUserObject().toString())) {
       return node;
     }
   }
   return null;
 }
 public void removeNode(DefaultMutableTreeNode selNode) {
   if (selNode == null) {
     return;
   }
   MutableTreeNode parent = (MutableTreeNode) (selNode.getParent());
   if (parent == null) {
     return;
   }
   MutableTreeNode toBeSelNode = getSibling(selNode);
   if (toBeSelNode == null) {
     toBeSelNode = parent;
   }
   TreeNode[] nodes = m_model.getPathToRoot(toBeSelNode);
   TreePath path = new TreePath(nodes);
   m_tree.scrollPathToVisible(path);
   m_tree.setSelectionPath(path);
   m_model.removeNodeFromParent(selNode);
 }
 private MutableTreeNode getSibling(DefaultMutableTreeNode selNode) {
   MutableTreeNode sibling = (MutableTreeNode) selNode.getPreviousSibling();
   if (sibling == null) {
     sibling = (MutableTreeNode) selNode.getNextSibling();
   }
   return sibling;
 }
 public static void main(String[] arg) {
   EditableTree editableTree = new EditableTree();
 }

}</source>





Swing Tree

   <source lang="java">

import java.awt.BorderLayout; import java.awt.ruponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.JTree; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreeCellRenderer; import javax.swing.tree.TreePath; public class SwingTree extends JFrame {

 JTextField textField = new JTextField();
 JScrollPane scrollPane = new JScrollPane();
 JTree tree;
 Renderer renderer = new Renderer();
 DefaultMutableTreeNode nba = new DefaultMutableTreeNode("National Basketball Association");
 DefaultMutableTreeNode western = new DefaultMutableTreeNode("Western Conference");
 DefaultMutableTreeNode pacific = new DefaultMutableTreeNode("Pacific Division Teams");
 DefaultMutableTreeNode midwest = new DefaultMutableTreeNode("Midwest Division Teams");
 DefaultMutableTreeNode denver = new DefaultMutableTreeNode("Denver");
 DefaultMutableTreeNode eastern = new DefaultMutableTreeNode("Eastern Conference");
 DefaultMutableTreeNode atlantic = new DefaultMutableTreeNode("Atlantic Division Teams");
 DefaultMutableTreeNode central = new DefaultMutableTreeNode("Central Division Teams");
 public SwingTree() {
   nba.add(western);
   nba.add(eastern);
   western.add(pacific);
   western.add(midwest);
   eastern.add(atlantic);
   eastern.add(central);
   pacific.add(new DefaultMutableTreeNode("Los Angeles (Lakers)"));
   pacific.add(new DefaultMutableTreeNode("Los Angeles (Clippers)"));
   pacific.add(new DefaultMutableTreeNode("San Francisco"));
   pacific.add(new DefaultMutableTreeNode("Seattle"));
   pacific.add(new DefaultMutableTreeNode("Phoenix"));
   pacific.add(new DefaultMutableTreeNode("Portland"));
   pacific.add(new DefaultMutableTreeNode("Sacramento"));
   
   
   midwest.add(new DefaultMutableTreeNode("Utah"));
   midwest.add(new DefaultMutableTreeNode("San Antonio"));
   midwest.add(new DefaultMutableTreeNode("Houston"));
   midwest.add(new DefaultMutableTreeNode("Minnesota"));
   midwest.add(new DefaultMutableTreeNode("Vancouver"));
   midwest.add(new DefaultMutableTreeNode("Dallas"));
  
   midwest.add(denver);
   atlantic.add(new DefaultMutableTreeNode("Miami"));
   atlantic.add(new DefaultMutableTreeNode("New York"));
   atlantic.add(new DefaultMutableTreeNode("New Jersey"));
   atlantic.add(new DefaultMutableTreeNode("Washington"));
   atlantic.add(new DefaultMutableTreeNode("Orlando"));
   atlantic.add(new DefaultMutableTreeNode("Boston"));
   atlantic.add(new DefaultMutableTreeNode("Philadelphia"));
   
   central.add(new DefaultMutableTreeNode("Chicago"));
   central.add(new DefaultMutableTreeNode("Indiana"));
   central.add(new DefaultMutableTreeNode("Charlotte"));
   central.add(new DefaultMutableTreeNode("Atlanta"));
   central.add(new DefaultMutableTreeNode("Cleveland"));
   central.add(new DefaultMutableTreeNode("Detroit"));
   central.add(new DefaultMutableTreeNode("Milwaukee"));
   central.add(new DefaultMutableTreeNode("Toronto"));
   tree = new JTree(nba);
   getContentPane().setLayout(new BorderLayout());
   tree.setCellRenderer(renderer);
   tree.addTreeSelectionListener(new TreeHandler());
   scrollPane.getViewport().add(tree);
   getContentPane().add("Center", scrollPane);
   getContentPane().add("South", textField);
   setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   setSize(500, 500);
   setVisible(true);
 }
 public static void main(String[] args) {
   SwingTree app = new SwingTree();
 }
 public class TreeHandler implements TreeSelectionListener {
   public void valueChanged(TreeSelectionEvent e) {
     TreePath path = e.getPath();
     String text = path.getPathComponent(path.getPathCount() - 1).toString();
     if (path.getPathCount() > 3) {
       text += ": ";
       text += Integer.toString((int) (Math.random() * 50)) + " Wins ";
       text += Integer.toString((int) (Math.random() * 50)) + " Losses";
     }
     textField.setText(text);
   }
 }

} class Renderer extends JLabel implements TreeCellRenderer {

 public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected,
     boolean expanded, boolean leaf, int row, boolean hasFocus) {
   setText(value.toString() + "                   ");
   return this;
 }

}</source>





Tree with custom icon

   <source lang="java">

/*

* Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
*   - Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*
*   - Redistributions in binary form must reproduce the above copyright
*     notice, this list of conditions and the following disclaimer in the
*     documentation and/or other materials provided with the distribution.
*
*   - Neither the name of Sun Microsystems nor the names of its
*     contributors may be used to endorse or promote products derived
*     from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/**

* A 1.4 application that requires the following additional files:
*   TreeDemoHelp.html
*    arnold.html
*    bloch.html
*    chan.html
*    jls.html
*    swingtutorial.html
*    tutorial.html
*    tutorialcont.html
*    vm.html
*/

import java.awt.ruponent; import java.awt.Dimension; import java.awt.GridLayout; import java.io.IOException; import java.net.URL; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JEditorPane; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTree; import javax.swing.ToolTipManager; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.TreeSelectionModel; public class TreeIconDemo2 extends JPanel implements TreeSelectionListener {

 private JEditorPane htmlPane;
 private JTree tree;
 private URL helpURL;
 private static boolean DEBUG = false;
 public TreeIconDemo2() {
   super(new GridLayout(1, 0));
   // Create the nodes.
   DefaultMutableTreeNode top = new DefaultMutableTreeNode("The Java Series");
   createNodes(top);
   // Create a tree that allows one selection at a time.
   tree = new JTree(top);
   tree.getSelectionModel().setSelectionMode(
       TreeSelectionModel.SINGLE_TREE_SELECTION);
   // Enable tool tips.
   ToolTipManager.sharedInstance().registerComponent(tree);
   // Set the icon for leaf nodes.
   ImageIcon tutorialIcon = createImageIcon("images/middle.gif");
   if (tutorialIcon != null) {
     tree.setCellRenderer(new MyRenderer(tutorialIcon));
   } else {
     System.err.println("Tutorial icon missing; using default.");
   }
   // Listen for when the selection changes.
   tree.addTreeSelectionListener(this);
   // Create the scroll pane and add the tree to it.
   JScrollPane treeView = new JScrollPane(tree);
   // Create the HTML viewing pane.
   htmlPane = new JEditorPane();
   htmlPane.setEditable(false);
   initHelp();
   JScrollPane htmlView = new JScrollPane(htmlPane);
   // Add the scroll panes to a split pane.
   JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
   splitPane.setTopComponent(treeView);
   splitPane.setBottomComponent(htmlView);
   Dimension minimumSize = new Dimension(100, 50);
   htmlView.setMinimumSize(minimumSize);
   treeView.setMinimumSize(minimumSize);
   splitPane.setDividerLocation(100); // XXX: ignored in some releases
   // of Swing. bug 4101306
   // workaround for bug 4101306:
   // treeView.setPreferredSize(new Dimension(100, 100));
   splitPane.setPreferredSize(new Dimension(500, 300));
   // Add the split pane to this panel.
   add(splitPane);
 }
 /** Required by TreeSelectionListener interface. */
 public void valueChanged(TreeSelectionEvent e) {
   DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree
       .getLastSelectedPathComponent();
   if (node == null)
     return;
   Object nodeInfo = node.getUserObject();
   if (node.isLeaf()) {
     BookInfo book = (BookInfo) nodeInfo;
     displayURL(book.bookURL);
     if (DEBUG) {
       System.out.print(book.bookURL + ":  \n    ");
     }
   } else {
     displayURL(helpURL);
   }
   if (DEBUG) {
     System.out.println(nodeInfo.toString());
   }
 }
 private class BookInfo {
   public String bookName;
   public URL bookURL;
   public BookInfo(String book, String filename) {
     bookName = book;
     bookURL = TreeIconDemo2.class.getResource(filename);
     if (bookURL == null) {
       System.err.println("Couldn"t find file: " + filename);
     }
   }
   public String toString() {
     return bookName;
   }
 }
 private void initHelp() {
   String s = "TreeDemoHelp.html";
   helpURL = TreeIconDemo2.class.getResource(s);
   if (helpURL == null) {
     System.err.println("Couldn"t open help file: " + s);
   } else if (DEBUG) {
     System.out.println("Help URL is " + helpURL);
   }
   displayURL(helpURL);
 }
 private void displayURL(URL url) {
   try {
     if (url != null) {
       htmlPane.setPage(url);
     } else { // null url
       htmlPane.setText("File Not Found");
       if (DEBUG) {
         System.out.println("Attempted to display a null URL.");
       }
     }
   } catch (IOException e) {
     System.err.println("Attempted to read a bad URL: " + url);
   }
 }
 private void createNodes(DefaultMutableTreeNode top) {
   DefaultMutableTreeNode category = null;
   DefaultMutableTreeNode book = null;
   category = new DefaultMutableTreeNode("Books for Java Programmers");
   top.add(category);
   // original Tutorial
   book = new DefaultMutableTreeNode(new BookInfo(
       "The Java Tutorial: A Short Course on the Basics", "tutorial.html"));
   category.add(book);
   // Tutorial Continued
   book = new DefaultMutableTreeNode(
       new BookInfo("The Java Tutorial Continued: The Rest of the JDK",
           "tutorialcont.html"));
   category.add(book);
   // JFC Swing Tutorial
   book = new DefaultMutableTreeNode(new BookInfo(
       "The JFC Swing Tutorial: A Guide to Constructing GUIs",
       "swingtutorial.html"));
   category.add(book);
   // Bloch
   book = new DefaultMutableTreeNode(new BookInfo(
       "Effective Java Programming Language Guide", "bloch.html"));
   category.add(book);
   // Arnold/Gosling
   book = new DefaultMutableTreeNode(new BookInfo(
       "The Java Programming Language", "arnold.html"));
   category.add(book);
   // Chan
   book = new DefaultMutableTreeNode(new BookInfo(
       "The Java Developers Almanac", "chan.html"));
   category.add(book);
   category = new DefaultMutableTreeNode("Books for Java Implementers");
   top.add(category);
   // VM
   book = new DefaultMutableTreeNode(new BookInfo(
       "The Java Virtual Machine Specification", "vm.html"));
   category.add(book);
   // Language Spec
   book = new DefaultMutableTreeNode(new BookInfo(
       "The Java Language Specification", "jls.html"));
   category.add(book);
 }
 /** Returns an ImageIcon, or null if the path was invalid. */
 protected static ImageIcon createImageIcon(String path) {
   java.net.URL imgURL = TreeIconDemo2.class.getResource(path);
   if (imgURL != null) {
     return new ImageIcon(imgURL);
   } else {
     System.err.println("Couldn"t find file: " + path);
     return null;
   }
 }
 /**
  * Create the GUI and show it. For thread safety, this method should be
  * invoked from the event-dispatching thread.
  */
 private static void createAndShowGUI() {
   // Create and set up the window.
   JFrame frame = new JFrame("TreeIconDemo2");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   // Create and set up the content pane.
   TreeIconDemo2 newContentPane = new TreeIconDemo2();
   newContentPane.setOpaque(true); // content panes must be opaque
   frame.setContentPane(newContentPane);
   // Display the window.
   frame.pack();
   frame.setVisible(true);
 }
 public static void main(String[] args) {
   // Schedule a job for the event-dispatching thread:
   // creating and showing this application"s GUI.
   javax.swing.SwingUtilities.invokeLater(new Runnable() {
     public void run() {
       createAndShowGUI();
     }
   });
 }
 private class MyRenderer extends DefaultTreeCellRenderer {
   Icon tutorialIcon;
   public MyRenderer(Icon icon) {
     tutorialIcon = icon;
   }
   public Component getTreeCellRendererComponent(JTree tree, Object value,
       boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
     super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row,
         hasFocus);
     if (leaf && isTutorialBook(value)) {
       setIcon(tutorialIcon);
       setToolTipText("This book is in the Tutorial series.");
     } else {
       setToolTipText(null); // no tool tip
     }
     return this;
   }
   protected boolean isTutorialBook(Object value) {
     DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
     BookInfo nodeInfo = (BookInfo) (node.getUserObject());
     String title = nodeInfo.bookName;
     if (title.indexOf("Tutorial") >= 0) {
       return true;
     }
     return false;
   }
 }

}</source>