Java Tutorial/Swing/JTree Node

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

Adding a Node to a JTree Component

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());
  }
}





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

/*
 * 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);
  }
}





CheckBox Tree node

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;
  }
}





Converting All Nodes in a JTree Component to a TreePath Array

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);
      }
    }
  }
}





Delete tree node

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);
    }
  }
}





Expanding or Collapsing All Nodes in a JTree Component

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);
  }
}





Expression Tree

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();
  }
}





Get child count, depth, leaf count

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();
  }
}





Get path for all expanded or not expanded tree pathes

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);
      }
    }
  }
}





JTree node mouse click event

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("");
  }
}





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

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);
  }
}





Removing a Node to a JTree Component

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);
  }
}





Searching node in a JTree

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();
  }
}





Swing Tree

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;
  }
}





Tree with custom icon

/*
 * 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;
    }
  }
}