Java/Swing JFC/Tree

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

Содержание

Add and remove tree Node and expand the tree node

   <source lang="java">
 

import java.awt.BorderLayout; import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; public class ModelJTree extends JFrame {

 private JTree tree;
 private DefaultTreeModel model;
 private DefaultMutableTreeNode rootNode;
 public ModelJTree() {
   DefaultMutableTreeNode philosophersNode = getPhilosopherTree();
   model = new DefaultTreeModel(philosophersNode);
   tree = new JTree(model);
   JButton addButton = new JButton("Add Philosopher");
   addButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent event) {
       addPhilosopher();
     }
   });
   JButton removeButton = new JButton("Remove Selected Philosopher");
   removeButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent event) {
       removeSelectedPhilosopher();
     }
   });
   JPanel inputPanel = new JPanel();
   inputPanel.add(addButton);
   inputPanel.add(removeButton);
   Container container = getContentPane();
   container.add(new JScrollPane(tree), BorderLayout.CENTER);
   container.add(inputPanel, BorderLayout.NORTH);
   setDefaultCloseOperation(EXIT_ON_CLOSE);
   setSize(400, 300);
   setVisible(true);
 }
 private void addPhilosopher() {
   DefaultMutableTreeNode parent = getSelectedNode();
   if (parent == null) {
     JOptionPane.showMessageDialog(ModelJTree.this, "Select an era.", "Error",
         JOptionPane.ERROR_MESSAGE);
     return;
   }
   String name = JOptionPane.showInputDialog(ModelJTree.this, "Enter Name:");
   model.insertNodeInto(new DefaultMutableTreeNode(name), parent, parent.getChildCount());
 }
 private void removeSelectedPhilosopher() {
   DefaultMutableTreeNode selectedNode = getSelectedNode();
   if (selectedNode != null)
     model.removeNodeFromParent(selectedNode);
 }
 private DefaultMutableTreeNode getSelectedNode() {
   return (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
 }
 private DefaultMutableTreeNode getPhilosopherTree() {
   DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("Philosophers");
   DefaultMutableTreeNode ancient = new DefaultMutableTreeNode("Ancient");
   rootNode.add(ancient);
   ancient.add(new DefaultMutableTreeNode("Socrates"));
   DefaultMutableTreeNode medieval = new DefaultMutableTreeNode("Medieval");
   rootNode.add(medieval);
   return rootNode;
 }
 public static void main(String args[]) {
   new ModelJTree();
 }

}


 </source>
   
  
 
  



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>
   
  
 
  



Adding editable nodes to JTree

   <source lang="java">
 

import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; public class Main extends JFrame {

 DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("J");
 DefaultTreeModel model = new DefaultTreeModel(rootNode);
 JTree m_tree = new JTree(model);
 JButton addButton;
 public Main() {
   DefaultMutableTreeNode forums = new DefaultMutableTreeNode("F");
   forums.add(new DefaultMutableTreeNode("T"));
   DefaultMutableTreeNode articles = new DefaultMutableTreeNode("A");
   articles.add(new DefaultMutableTreeNode("1"));
   DefaultMutableTreeNode examples = new DefaultMutableTreeNode("E");
   examples.add(new DefaultMutableTreeNode("2"));
   rootNode.add(forums);
   rootNode.add(articles);
   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();
   addButton = new JButton("Add Node");
   addButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent event) {
       DefaultMutableTreeNode selNode = (DefaultMutableTreeNode) m_tree
           .getLastSelectedPathComponent();
       if (selNode != null) {
         DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("New Node");
         model.insertNodeInto(newNode, selNode, selNode.getChildCount());
         TreeNode[] nodes = model.getPathToRoot(newNode);
         TreePath path = new TreePath(nodes);
         m_tree.scrollPathToVisible(path);
         m_tree.setSelectionPath(path);
         m_tree.startEditingAtPath(path);
       }
     }
   });
   panel.add(addButton);
   getContentPane().add(panel, BorderLayout.SOUTH);
   setSize(300, 400);
   setVisible(true);
 }
 public static void main(String[] arg) {
   new Main();
 }

}


 </source>
   
  
 
  



Add Tree to JScrollPane

   <source lang="java">
 

import java.awt.BorderLayout; import java.awt.Container; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; public class TreeSample {

 public static void main(String args[]) {
   JFrame f = new JFrame("JTree Sample");
   f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   Container content = f.getContentPane();
   JTree tree = new JTree();
   JScrollPane scrollPane = new JScrollPane(tree);
   content.add(scrollPane, BorderLayout.CENTER);
   f.setSize(300, 200);
   f.setVisible(true);
 }

}


 </source>
   
  
 
  



Allow multiple selections of visible nodes

   <source lang="java">
 

import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.tree.TreeSelectionModel; public class TreeDISCONTIGUOUSSelection {

 public static void main(String[] argv) {
   JTree tree = new JTree();
   tree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
   JFrame frame = new JFrame("tree DISCONTIGUOUS selection");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.add(new JScrollPane(tree));
   frame.setSize(380, 320);
   frame.setLocationRelativeTo(null);
   frame.setVisible(true);
 }

}


 </source>
   
  
 
  



Allow only a single node to be selected (default)

   <source lang="java">
 

import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.tree.TreeSelectionModel;

public class TreeSingleSelection {

 public static void main(String[] argv) {
   JTree tree = new JTree();
   tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
   JFrame frame = new JFrame("Tree single selection");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.add(new JScrollPane(tree));
   frame.setSize(380, 320);
   frame.setLocationRelativeTo(null);
   frame.setVisible(true);
 }

}


 </source>
   
  
 
  



Allow selection to span one vertical contiguous set of visible nodes

   <source lang="java">
 

import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.tree.TreeSelectionModel; public class TreeCONTIGUOUSSelection {

 public static void main(String[] argv) {
   JTree tree = new JTree();
   tree.getSelectionModel().setSelectionMode(TreeSelectionModel.CONTIGUOUS_TREE_SELECTION);
   JFrame frame = new JFrame("Tree CONTIGUOUS selection");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.add(new JScrollPane(tree));
   frame.setSize(380, 320);
   frame.setLocationRelativeTo(null);
   frame.setVisible(true);
 }

}


 </source>
   
  
 
  



All rows will be given 15 pixels of height

   <source lang="java">
 

import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; public class TreeRowHeight15 {

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

}


 </source>
   
  
 
  



Ancestor Tree with Icons

   <source lang="java">
 

import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; import javax.swing.border.*; import javax.swing.event.*; import javax.swing.tree.*; public class AncestorTree extends JFrame {

 public static ImageIcon ICON_SELF = 
   new ImageIcon("myself.gif");
 public static ImageIcon ICON_MALE = 
   new ImageIcon("male.gif");
 public static ImageIcon ICON_FEMALE = 
   new ImageIcon("female.gif");
 protected JTree  m_tree;
 protected DefaultTreeModel m_model;
 protected IconCellRenderer m_renderer;
 protected IconCellEditor m_editor;
 public AncestorTree()
 {
   super("Ancestor Tree");
   setSize(400, 300);
       DefaultMutableTreeNode top = new DefaultMutableTreeNode( 
     new IconData(ICON_SELF, "Myself"));
   addAncestors(top);
   m_model = new DefaultTreeModel(top);
   m_tree = new JTree(m_model);
   m_tree.getSelectionModel().setSelectionMode(
     TreeSelectionModel.SINGLE_TREE_SELECTION);
   m_tree.setShowsRootHandles(true); 
   m_tree.setEditable(true);
   m_renderer = new IconCellRenderer();
   m_tree.setCellRenderer(m_renderer); 
   m_editor = new IconCellEditor(m_tree);
   m_tree.setCellEditor(m_editor);
   m_tree.setInvokesStopCellEditing(true);
   m_tree.addMouseListener(new TreeExpander()); 
   JScrollPane s = new JScrollPane();
   s.getViewport().add(m_tree);
   getContentPane().add(s, BorderLayout.CENTER);
   WindowListener wndCloser = new WindowAdapter()
   {
     public void windowClosing(WindowEvent e) 
     {
       System.exit(0);
     }
   };
   addWindowListener(wndCloser);
   setVisible(true);
 }
 public boolean addAncestors(DefaultMutableTreeNode node)
 {
   if (node.getChildCount() > 0)
     return false;
   Object obj = node.getUserObject();
   if (obj == null)
     return false;
   node.add(new DefaultMutableTreeNode( new IconData(
     ICON_MALE, "Father of: "+obj.toString()) ));
   node.add(new DefaultMutableTreeNode( new IconData(
     ICON_FEMALE, "Mother of: "+obj.toString()) ));
   return true;
 }
 public static void main(String argv[]) 
 {
   new AncestorTree();
 }
 class TreeExpander 
   extends MouseAdapter 
 {
   public void mouseClicked(MouseEvent e)
   {
     if (e.getClickCount() == 2)
     {
       TreePath selPath = m_tree.getPathForLocation(
         e.getX(), e.getY());
       if (selPath == null)
         return;
       DefaultMutableTreeNode node = 
         (DefaultMutableTreeNode)(selPath.
           getLastPathComponent());
       if (node!=null && addAncestors(node))
       {
         m_tree.expandPath(selPath);
         m_tree.repaint();
       }
     }
   }
 }

} class IconCellRenderer

 extends    JLabel 
 implements TreeCellRenderer

{

 protected Color m_textSelectionColor;
 protected Color m_textNonSelectionColor;
 protected Color m_bkSelectionColor;
 protected Color m_bkNonSelectionColor;
 protected Color m_borderSelectionColor;
 protected boolean m_selected;
 public IconCellRenderer()
 {
   super();
   m_textSelectionColor = UIManager.getColor(
     "Tree.selectionForeground");
   m_textNonSelectionColor = UIManager.getColor(
     "Tree.textForeground");
   m_bkSelectionColor = UIManager.getColor(
     "Tree.selectionBackground");
   m_bkNonSelectionColor = UIManager.getColor(
     "Tree.textBackground");
   m_borderSelectionColor = UIManager.getColor(
     "Tree.selectionBorderColor");
   setOpaque(false);
 }
 public Component getTreeCellRendererComponent(JTree tree, 
   Object value, boolean sel, boolean expanded, boolean leaf, 
   int row, boolean hasFocus) 
   
 {
   DefaultMutableTreeNode node = 
     (DefaultMutableTreeNode)value;
   Object obj = node.getUserObject();
   setText(obj.toString());
   if (obj instanceof IconData)
   {
     IconData idata = (IconData)obj;
     if (expanded)
       setIcon(idata.getOpenIcon());
     else
       setIcon(idata.getIcon());
   }
   else
     setIcon(null);
   setFont(tree.getFont());
   setForeground(sel ? m_textSelectionColor : 
     m_textNonSelectionColor);
   setBackground(sel ? m_bkSelectionColor : 
     m_bkNonSelectionColor);
   m_selected = sel;
   return this;
 }
   
 public void paint(Graphics g) 
 {
   Color bColor = getBackground();
   Icon icon = getIcon();
   g.setColor(bColor);
   int offset = 0;
   if(icon != null && getText() != null) 
     offset = (icon.getIconWidth() + getIconTextGap());
   g.fillRect(offset, 0, getWidth() - 1 - offset,
     getHeight() - 1);
   
   if (m_selected) 
   {
     g.setColor(m_borderSelectionColor);
     g.drawRect(offset, 0, getWidth()-1-offset, getHeight()-1);
   }
   super.paint(g);
   }

} class IconData {

 protected Icon   m_icon;
 protected Icon   m_openIcon;
 protected Object m_data;
 public IconData(Icon icon, Object data)
 {
   m_icon = icon;
   m_openIcon = null;
   m_data = data;
 }
 public IconData(Icon icon, Icon openIcon, Object data)
 {
   m_icon = icon;
   m_openIcon = openIcon;
   m_data = data;
 }
 public Icon getIcon() 
 { 
   return m_icon;
 }
 public Icon getOpenIcon() 
 { 
   return m_openIcon!=null ? m_openIcon : m_icon;
 }
 public Object getObject() 
 { 
   return m_data;
 }
 public String toString() 
 { 
   return m_data.toString();
 }

} class IconCellEditor

 extends    JLabel 
 implements TreeCellEditor, ActionListener

{

 protected JTree      m_tree = null;
 protected JTextField m_editor = null;
 protected IconData   m_item = null;
 protected int        m_lastRow = -1;
 protected long       m_lastClick = 0;
 protected Vector     m_listeners = null;
 public IconCellEditor(JTree tree)
 {
   super();
   m_tree = tree;
   m_listeners = new Vector();
 }
 public Component getTreeCellEditorComponent(JTree tree, 
   Object value, boolean isSelected, boolean expanded, 
   boolean leaf, int row)
 {
   if (value instanceof DefaultMutableTreeNode)
   {
     DefaultMutableTreeNode node = 
       (DefaultMutableTreeNode)value;
     Object obj = node.getUserObject();
     if (obj instanceof IconData)
     {
       IconData idata = (IconData)obj;
       m_item = idata;
       // Reserve some more space...
       setText(idata.toString()+"     "); 
       setIcon(idata.m_icon);
       setFont(tree.getFont());
       return this;
     }
   }
   // We don"t support other objects...
   return null;
 }
 public Object getCellEditorValue() 
 { 
   if (m_item != null && m_editor != null)
     m_item.m_data = m_editor.getText();
   return m_item; 
 }
 public boolean isCellEditable(EventObject evt) 
 { 
   if (evt instanceof MouseEvent)
   {
     MouseEvent mEvt = (MouseEvent)evt;
     if (mEvt.getClickCount() == 1)
     {
       int row = m_tree.getRowForLocation(mEvt.getX(), 
         mEvt.getY());
       if (row != m_lastRow)
       {
         m_lastRow = row;
         m_lastClick = System.currentTimeMillis();
         return false;
       }
       else if (System.currentTimeMillis()-m_lastClick 
         > 1000)
       {
         m_lastRow = -1;
         m_lastClick = 0;
         prepareEditor();
         mEvt.consume();
         return true;
       }
       else
         return false; 
     }
   }
   return false; 
 }
   protected void prepareEditor() 
 {
   if (m_item == null)
     return;
   String str = m_item.toString();
   m_editor = new JTextField(str);
   m_editor.addActionListener(this);
   m_editor.selectAll();
   m_editor.setFont(m_tree.getFont());
   
   add(m_editor);
   revalidate();
   TreePath path = m_tree.getPathForRow(m_lastRow);
   m_tree.startEditingAtPath(path);
 }
   protected void removeEditor() 
 {
   if (m_editor != null)
   {
     remove(m_editor);
     m_editor.setVisible(false);
     m_editor = null;
     m_item = null;
   }
 }
 public void doLayout()
 {
   super.doLayout();
   if (m_editor != null)
   {
     int offset = getIconTextGap();
     if (getIcon() != null)
       offset += getIcon().getIconWidth();
     Dimension cSize = getSize();
     m_editor.setBounds(offset, 0, cSize.width - offset, 
       cSize.height);
   }
 }
 public boolean shouldSelectCell(EventObject evt) 
 { 
   return true; 
 }
 public boolean stopCellEditing() 
 {
   if (m_item != null)
     m_item.m_data = m_editor.getText();
   ChangeEvent e = new ChangeEvent(this);
   for (int k=0; k<m_listeners.size(); k++)
   {
     CellEditorListener l = (CellEditorListener)m_listeners.
       elementAt(k);
     l.editingStopped(e);
   }
   removeEditor();
   return true; 
 }
 public void cancelCellEditing() 
 {
   ChangeEvent e = new ChangeEvent(this);
   for (int k=0; k<m_listeners.size(); k++)
   {
     CellEditorListener l = (CellEditorListener)m_listeners.
       elementAt(k);
     l.editingCanceled(e);
   }
   removeEditor();
 }
 public void addCellEditorListener(CellEditorListener l) 
 {
   m_listeners.addElement(l);
 }
 public void removeCellEditorListener(CellEditorListener l)
 {
   m_listeners.removeElement(l);
 }
 public void actionPerformed(ActionEvent e)
 {
   stopCellEditing();
   m_tree.stopEditing();
 }

}



 </source>
   
  
 
  



A sample component for dragging and dropping a collection of files into a tree.

   <source lang="java">
 

/* Java Swing, 2nd Edition By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole ISBN: 0-596-00408-7 Publisher: O"Reilly

  • /

// FSTest.java //A quick test environment for the FSTree component. // import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.io.File; import java.io.IOException; import java.util.Iterator; import java.util.List; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.TransferHandler; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeModel; import javax.swing.tree.TreeNode; public class FSTest extends JFrame {

 public FSTest() {
   super("FSTree Component Test");
   setSize(300, 300);
   setDefaultCloseOperation(EXIT_ON_CLOSE);
   FSTree fst = new FSTree(new DefaultMutableTreeNode("Starter"));
   getContentPane().add(new JScrollPane(fst));
   setVisible(true);
 }
 public static void main(String args[]) {
   new FSTest();
 }

} //FSTree.java //A sample component for dragging & dropping a collection of files //into a tree. // class FSTree extends JTree {

 public FSTree() {
   super();
   init();
 }
 public FSTree(TreeModel newModel) {
   super(newModel);
   init();
 }
 public FSTree(TreeNode root) {
   super(root);
   init();
 }
 public FSTree(TreeNode root, boolean asks) {
   super(root, asks);
   init();
 }
 private void init() {
   // We don"t want to export anything from this tree, only import
   setDragEnabled(false);
   setTransferHandler(new FSTransfer());
 }
 public class FSTransfer extends TransferHandler {
   public boolean importData(JComponent comp, Transferable t) {
     // Make sure we have the right starting points
     if (!(comp instanceof FSTree)) {
       return false;
     }
     if (!t.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
       return false;
     }
     // Grab the tree, its model and the root node
     FSTree tree = (FSTree) comp;
     DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
     DefaultMutableTreeNode root = (DefaultMutableTreeNode) model
         .getRoot();
     try {
       List data = (List) t
           .getTransferData(DataFlavor.javaFileListFlavor);
       Iterator i = data.iterator();
       while (i.hasNext()) {
         File f = (File) i.next();
         root.add(new DefaultMutableTreeNode(f.getName()));
       }
       model.reload();
       return true;
     } catch (UnsupportedFlavorException ufe) {
       System.err.println("Ack! we should not be here.\nBad Flavor.");
     } catch (IOException ioe) {
       System.out.println("Something failed during import:\n" + ioe);
     }
     return false;
   }
   // We only support file lists on FSTrees...
   public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
     if (comp instanceof FSTree) {
       for (int i = 0; i < transferFlavors.length; i++) {
         if (!transferFlavors[i]
             .equals(DataFlavor.javaFileListFlavor)) {
           return false;
         }
       }
       return true;
     }
     return false;
   }
 }

}



 </source>
   
  
 
  



A simple test to see how we can build a tree and populate it

   <source lang="java">
 

/* Java Swing, 2nd Edition By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole ISBN: 0-596-00408-7 Publisher: O"Reilly

  • /

// TestTree.java //A simple test to see how we can build a tree and populate it. We build //the tree structure up by hand in this case. // import java.awt.BorderLayout; import javax.swing.JFrame; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; public class TestTree extends JFrame {

 JTree tree;
 DefaultTreeModel treeModel;
 public TestTree() {
   super("Tree Test Example");
   setSize(400, 300);
   setDefaultCloseOperation(EXIT_ON_CLOSE);
 }
 public void init() {
   // Build up a bunch of TreeNodes. We use DefaultMutableTreeNode because
   // the
   // DefaultTreeModel can use it to build a complete tree.
   DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
   DefaultMutableTreeNode subroot = new DefaultMutableTreeNode("SubRoot");
   DefaultMutableTreeNode leaf1 = new DefaultMutableTreeNode("Leaf 1");
   DefaultMutableTreeNode leaf2 = new DefaultMutableTreeNode("Leaf 2");
   // Build our tree model starting at the root node, and then make a JTree
   // out
   // of that.
   treeModel = new DefaultTreeModel(root);
   tree = new JTree(treeModel);
   // Build the tree up from the nodes we created.
   treeModel.insertNodeInto(subroot, root, 0);
   // Or, more succinctly:
   subroot.add(leaf1);
   root.add(leaf2);
   // Display it.
   getContentPane().add(tree, BorderLayout.CENTER);
 }
 public static void main(String args[]) {
   TestTree tt = new TestTree();
   tt.init();
   tt.setVisible(true);
 }

}



 </source>
   
  
 
  



A tree with component

   <source lang="java">
 

/* Definitive Guide to Swing for Java 2, Second Edition By John Zukowski ISBN: 1-893115-78-X Publisher: APress

  • /

import java.awt.BorderLayout; import java.awt.Font; import java.util.Vector; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.UIManager; public class ComponentHier {

 public static void main(String args[]) {
   JFrame frame = new JFrame("JComponent Hierarchy");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   Font font = (Font) UIManager.get("Tree.font");
   font = new Font(font.getFontName(), Font.BOLD, font.getSize() - 3);
   UIManager.put("Tree.font", font);
   Vector jEditorPaneVector = new NamedVector("JEditorPane",
       new Object[] { "JTextPane" });
   Vector jTextFieldVector = new NamedVector("JTextField",
       new Object[] { "JPasswordField" });
   Vector jTextComponentVector = new NamedVector(
       "JTextComponent",
       new Object[] { jEditorPaneVector, "JTextArea", jTextFieldVector });
   Vector jLayeredPaneVector = new NamedVector("JLayeredPane",
       new Object[] { "JDesktopPane" });
   Vector jToggleButtonVector = new NamedVector("JToggleButton",
       new Object[] { "JCheckBox", "JRadioButton" });
   Vector jMenuItemVector = new NamedVector("JMenuItem", new Object[] {
       "JCheckBoxMenuItem", "JMenu", "JRadioButtonMenuItem" });
   Vector abstractButtonVector = new NamedVector(
       "Abstract Button",
       new Object[] { "JButton", jMenuItemVector, jToggleButtonVector });
   Object jComponentNodes[] = { abstractButtonVector, "JColorChooser",
       "JComboBox", "JFileChooser", "JInternalFrame", "JLabel",
       jLayeredPaneVector, "JList", "JMenuBar", "JOptionPane",
       "JPanel", "JPopupMenu", "JProgressBar", "JRootPane",
       "JScrollBar", "JScrollPane", "JSeparator", "JSlider",
       "JSplitPane", "JTabbedPane", "JTable", jTextComponentVector,
       "JToolBar", "JTree", "JViewPort" };
   Vector jComponentVector = new NamedVector("JComponent", jComponentNodes);
   Object rootNodes[] = { jComponentVector };
   Vector rootVector = new NamedVector("Root", rootNodes);
   JTree tree = new JTree(rootVector);
   tree.putClientProperty("JTree.lineStyle", "Angled");
   JScrollPane scrollPane = new JScrollPane(tree);
   frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
   frame.setSize(250, 480);
   frame.setVisible(true);
 }

} class NamedVector extends Vector {

 String name;
 public NamedVector(String name) {
   this.name = name;
 }
 public NamedVector(String name, Object elements[]) {
   this.name = name;
   for (int i = 0, n = elements.length; i < n; i++) {
     add(elements[i]);
   }
 }
 public String toString() {
   return "[" + name + "]";
 }

}


 </source>
   
  
 
  



Build a tree and customize its icons

   <source lang="java">
 

/* Java Swing, 2nd Edition By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole ISBN: 0-596-00408-7 Publisher: O"Reilly

  • /

// TestTree4.java //Another test to see how we can build a tree and customize its icons. //This example does not affect the icons of other trees. // import java.awt.BorderLayout; import java.util.Hashtable; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JSplitPane; import javax.swing.JTree; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.DefaultTreeModel; public class TestTree4 extends JFrame {

 JTree tree1, tree2;
 DefaultTreeModel treeModel;
 public TestTree4() {
   super("Custom Icon Example");
   setSize(350, 450);
   setDefaultCloseOperation(EXIT_ON_CLOSE);
   // Build the hierarchy of containers & objects
   String[] schoolyard = { "School", "Playground", "Parking Lot", "Field" };
   String[] mainstreet = { "Grocery", "Shoe Shop", "Five & Dime",
       "Post Office" };
   String[] highway = { "Gas Station", "Convenience Store" };
   String[] housing = { "Victorian_blue", "Faux Colonial",
       "Victorian_white" };
   String[] housing2 = { "Mission", "Ranch", "Condo" };
   Hashtable homeHash = new Hashtable();
   homeHash.put("Residential 1", housing);
   homeHash.put("Residential 2", housing2);
   Hashtable cityHash = new Hashtable();
   cityHash.put("School grounds", schoolyard);
   cityHash.put("Downtown", mainstreet);
   cityHash.put("Highway", highway);
   cityHash.put("Housing", homeHash);
   Hashtable worldHash = new Hashtable();
   worldHash.put("My First VRML World", cityHash);
   // Build our tree out of our big hashtable
   tree1 = new JTree(worldHash);
   tree2 = new JTree(worldHash);
   DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) tree2
       .getCellRenderer();
   renderer.setClosedIcon(new ImageIcon("door.closed.gif"));
   renderer.setOpenIcon(new ImageIcon("door.open.gif"));
   renderer.setLeafIcon(new ImageIcon("world.gif"));
   JSplitPane pane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, tree1,
       tree2);
   getContentPane().add(pane, BorderLayout.CENTER);
 }
 public static void main(String args[]) {
   TestTree4 tt = new TestTree4();
   tt.setVisible(true);
 }

}


 </source>
   
  
 
  



Build a tree and populate it from hashtables

   <source lang="java">
 

/* Java Swing, 2nd Edition By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole ISBN: 0-596-00408-7 Publisher: O"Reilly

  • /

// ObjectTree.java //A simple test to see how we can build a tree and populate it. This version //builds the tree from hashtables. // import java.awt.BorderLayout; import java.util.Hashtable; import javax.swing.JFrame; import javax.swing.JTree; public class ObjectTree extends JFrame {

 JTree tree;
 String[][] sampleData = { { "Amy" }, { "Brandon", "Bailey" }, { "Jodi" },
     { "Trent", "Garrett", "Paige", "Dylan" }, { "Donn" },
     { "Nancy", "Donald", "Phyllis", "John", "Pat" }, { "Ron" },
     { "Linda", "Mark", "Lois", "Marvin" } };
 public ObjectTree() {
   super("Hashtable Test");
   setSize(400, 300);
   setDefaultCloseOperation(EXIT_ON_CLOSE);
 }
 public void init() {
   Hashtable h = new Hashtable();
   // Build up the hashtable using every other entry in the String[][] as a
   // key
   // followed by a String[]"value."
   for (int i = 0; i < sampleData.length; i += 2) {
     h.put(sampleData[i][0], sampleData[i + 1]);
   }
   tree = new JTree(h);
   getContentPane().add(tree, BorderLayout.CENTER);
 }
 public static void main(String args[]) {
   ObjectTree tt = new ObjectTree();
   tt.init();
   tt.setVisible(true);
 }

}


 </source>
   
  
 
  



Build a tree based on DefaultMutableTreeNode

   <source lang="java">
 

// : c14:Trees.java // Simple Swing tree. Trees can be vastly more complex. // <applet code=Trees width=250 height=250></applet> // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JApplet; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; // Takes an array of Strings and makes the first // element a node and the rest leaves: class Branch {

 private DefaultMutableTreeNode r;
 public Branch(String[] data) {
   r = new DefaultMutableTreeNode(data[0]);
   for (int i = 1; i < data.length; i++)
     r.add(new DefaultMutableTreeNode(data[i]));
 }
 public DefaultMutableTreeNode node() {
   return r;
 }

} public class Trees extends JApplet {

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

} ///:~



 </source>
   
  
 
  



Changing and Removing the Default Icons in a JTree Component

   <source lang="java">
 

import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.UIManager; import javax.swing.tree.DefaultTreeCellRenderer; public class Main {

 public static void main(String[] argv) throws Exception {
   Icon leafIcon = new ImageIcon("leaf.gif");
   Icon openIcon = new ImageIcon("open.gif");
   Icon closedIcon = new ImageIcon("closed.gif");
   JTree tree = new JTree();
   DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) tree.getCellRenderer();
   renderer.setLeafIcon(leafIcon);
   renderer.setClosedIcon(closedIcon);
   renderer.setOpenIcon(openIcon);
   JFrame f = new JFrame();
   f.add(new JScrollPane(tree));
   f.setSize(300, 300);
   f.setVisible(true);
 }

}


 </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>
   
  
 
  



Creating a JTree Component

   <source lang="java">
 

import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; public class Main {

 public static void main(String[] argv) throws Exception {
   DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root Label");
   root.add(new DefaultMutableTreeNode("Node Label"));
   JTree tree = new JTree(root);
   
   JFrame f = new JFrame();
   f.add(new JScrollPane(tree));
   f.setSize(300,300);
   f.setVisible(true);
 }

}


 </source>
   
  
 
  



DefaultMutableTreeNode and user object

   <source lang="java">
 

/* From http://java.sun.ru/docs/books/tutorial/index.html */ /*

* Copyright (c) 2006 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:
*
* -Redistribution of source code must retain the above copyright notice, this
*  list of conditions and the following disclaimer.
*
* -Redistribution 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, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed, licensed or intended
* for use in the design, construction, operation or maintenance of any
* nuclear facility.
*/

/**

* 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 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.tree.DefaultMutableTreeNode; import javax.swing.tree.TreeSelectionModel; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.ToolTipManager; import javax.swing.ImageIcon; import javax.swing.Icon; import java.net.URL; import java.io.IOException; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.ruponent;

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() {
       //Make sure we have nice window decorations.
       JFrame.setDefaultLookAndFeelDecorated(true);
       //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>
   
  
 
  



DefaultMutableTreeNode Node Tree Sample

   <source lang="java">
 

import java.awt.BorderLayout; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; public class NodeTreeSample {

 public static void main(String args[]) {
   JFrame frame = new JFrame("Manual Nodes");
   DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
   DefaultMutableTreeNode mercury = new DefaultMutableTreeNode("Mercury");
   root.add(mercury);
   DefaultMutableTreeNode venus = new DefaultMutableTreeNode("Venus");
   root.add(venus);
   DefaultMutableTreeNode mars = new DefaultMutableTreeNode("Mars");
   root.add(mars);
   JTree tree = new JTree(root);
   JScrollPane scrollPane = new JScrollPane(tree);
   frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
   frame.setSize(300, 150);
   frame.setVisible(true);
 }

}


 </source>
   
  
 
  



Deleting nodes from JTree

   <source lang="java">
 

import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; 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 Main extends JFrame {

 DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("A");
 private DefaultTreeModel m_model = new DefaultTreeModel(rootNode);
 private JTree m_tree = new JTree(m_model);
 private JButton m_addButton;
 private JButton m_delButton;
 public Main() {
   DefaultMutableTreeNode forums = new DefaultMutableTreeNode("B");
   forums.add(new DefaultMutableTreeNode("T"));
   DefaultMutableTreeNode articles = new DefaultMutableTreeNode("A");
   articles.add(new DefaultMutableTreeNode("A"));
   DefaultMutableTreeNode examples = new DefaultMutableTreeNode("E");
   examples.add(new DefaultMutableTreeNode("E"));
   rootNode.add(forums);
   rootNode.add(articles);
   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 = new JButton("Add Node");
   m_addButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent event) {
       DefaultMutableTreeNode selNode = (DefaultMutableTreeNode) m_tree
           .getLastSelectedPathComponent();
       if (selNode == null) {
         return;
       }
       DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("New");
       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);
   getContentPane().add(panel, BorderLayout.SOUTH);
   m_delButton = new JButton("Delete Node");
   m_delButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent event) {
       DefaultMutableTreeNode selNode = (DefaultMutableTreeNode) m_tree
           .getLastSelectedPathComponent();
       if (selNode == null) {
         return;
       }
       MutableTreeNode parent = (MutableTreeNode) (selNode.getParent());
       if (parent == null) {
         return;
       }
       MutableTreeNode toBeSelNode = (MutableTreeNode) selNode.getPreviousSibling();
       if (toBeSelNode == null) {
         toBeSelNode = (MutableTreeNode) selNode.getNextSibling();
       }
       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);
     }
   });
   panel.add(m_delButton);
   getContentPane().add(panel, BorderLayout.SOUTH);
   setSize(300, 400);
   setVisible(true);
 }
 public static void main(String[] arg) {
   new Main();
 }

}


 </source>
   
  
 
  



Display a file system in a JTree view

   <source lang="java">
 

/*

* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002.
* All rights reserved. Software written by Ian F. Darwin and others.
* $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 2. 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
* 
* Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee
* cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s,
* pioneering role in inventing and promulgating (and standardizing) the Java 
* language and environment is gratefully acknowledged.
* 
* The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
* inventing predecessor languages C and C++ is also gratefully acknowledged.
*/

import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.io.File; import java.util.Collections; import java.util.Vector; import javax.swing.BoxLayout; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; /**

* Display a file system in a JTree view
* 
* @version $Id: FileTree.java,v 1.9 2004/02/23 03:39:22 ian Exp $
* @author Ian Darwin
*/

public class FileTree extends JPanel {

 /** Construct a FileTree */
 public FileTree(File dir) {
   setLayout(new BorderLayout());
   // Make a tree list with all the nodes, and make it a JTree
   JTree tree = new JTree(addNodes(null, dir));
   // Add a listener
   tree.addTreeSelectionListener(new TreeSelectionListener() {
     public void valueChanged(TreeSelectionEvent e) {
       DefaultMutableTreeNode node = (DefaultMutableTreeNode) e
           .getPath().getLastPathComponent();
       System.out.println("You selected " + node);
     }
   });
   // Lastly, put the JTree into a JScrollPane.
   JScrollPane scrollpane = new JScrollPane();
   scrollpane.getViewport().add(tree);
   add(BorderLayout.CENTER, scrollpane);
 }
 /** Add nodes from under "dir" into curTop. Highly recursive. */
 DefaultMutableTreeNode addNodes(DefaultMutableTreeNode curTop, File dir) {
   String curPath = dir.getPath();
   DefaultMutableTreeNode curDir = new DefaultMutableTreeNode(curPath);
   if (curTop != null) { // should only be null at root
     curTop.add(curDir);
   }
   Vector ol = new Vector();
   String[] tmp = dir.list();
   for (int i = 0; i < tmp.length; i++)
     ol.addElement(tmp[i]);
   Collections.sort(ol, String.CASE_INSENSITIVE_ORDER);
   File f;
   Vector files = new Vector();
   // Make two passes, one for Dirs and one for Files. This is #1.
   for (int i = 0; i < ol.size(); i++) {
     String thisObject = (String) ol.elementAt(i);
     String newPath;
     if (curPath.equals("."))
       newPath = thisObject;
     else
       newPath = curPath + File.separator + thisObject;
     if ((f = new File(newPath)).isDirectory())
       addNodes(curDir, f);
     else
       files.addElement(thisObject);
   }
   // Pass two: for files.
   for (int fnum = 0; fnum < files.size(); fnum++)
     curDir.add(new DefaultMutableTreeNode(files.elementAt(fnum)));
   return curDir;
 }
 public Dimension getMinimumSize() {
   return new Dimension(200, 400);
 }
 public Dimension getPreferredSize() {
   return new Dimension(200, 400);
 }
 /** Main: make a Frame, add a FileTree */
 public static void main(String[] av) {
   JFrame frame = new JFrame("FileTree");
   frame.setForeground(Color.black);
   frame.setBackground(Color.lightGray);
   Container cp = frame.getContentPane();
   if (av.length == 0) {
     cp.add(new FileTree(new File(".")));
   } else {
     cp.setLayout(new BoxLayout(cp, BoxLayout.X_AXIS));
     for (int i = 0; i < av.length; i++)
       cp.add(new FileTree(new File(av[i])));
   }
   frame.pack();
   frame.setVisible(true);
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 }

}



 </source>
   
  
 
  



Displaying Hierarchical Data within a JTree

   <source lang="java">
 

import java.awt.BorderLayout; import java.awt.Color; import java.awt.ruponent; import java.awt.Container; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollPane; 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 TreeIt {

 class MyCellRenderer extends JLabel implements TreeCellRenderer {
   MyCellRenderer() {
     setOpaque(true);
   }
   public Component getTreeCellRendererComponent(JTree tree, Object value,
       boolean selected, boolean expanded, boolean leaf, int row,
       boolean hasFocus) {
     StringBuffer text = new StringBuffer();
     if (expanded)
       text.append("E:");
     if (leaf)
       text.append("L:");
     if (hasFocus)
       text.append("H:");
     text.append(row + "->");
     text.append(value.toString());
     setBackground(selected ? Color.BLUE : Color.YELLOW);
     setForeground(selected ? Color.YELLOW : Color.BLUE);
     setText(text.toString());
     return this;
   }
 }
 public TreeIt() {
   JFrame f = new JFrame();
   DefaultMutableTreeNode root = new DefaultMutableTreeNode("Calendar");
   DefaultMutableTreeNode months = new DefaultMutableTreeNode("Months");
   root.add(months);
   String monthLabels[] = { "January", "February", "March", "April",
       "May", "June", "July", "August", "September", "October",
       "November", "December" };
   for (int i = 0, n = monthLabels.length; i < n; i++)
     months.add(new DefaultMutableTreeNode(monthLabels[i]));
   DefaultMutableTreeNode weeks = new DefaultMutableTreeNode("Weeks");
   root.add(weeks);
   String weekLabels[] = { "Monday", "Tuesday", "Wednesday", "Thursday",
       "Friday", "Saturday", "Sunday" };
   for (int i = 0, n = weekLabels.length; i < n; i++)
     weeks.add(new DefaultMutableTreeNode(weekLabels[i]));
   JTree jt = new JTree(root);
   jt.addTreeSelectionListener(new TreeSelectionListener() {
     public void valueChanged(TreeSelectionEvent e) {
       TreePath path = e.getPath();
       System.out.println("Picked: " + path.getLastPathComponent());
       Object elements[] = path.getPath();
       for (int i = 0, n = elements.length; i < n; i++) {
         System.out.print("->" + elements[i]);
       }
       System.out.println();
     }
   });
   DefaultMutableTreeNode lastLeaf = root.getLastLeaf();
   TreePath path = new TreePath(lastLeaf.getPath());
   jt.setSelectionPath(path);
   jt.setCellRenderer(new MyCellRenderer());
   JScrollPane jsp = new JScrollPane(jt);
   Container c = f.getContentPane();
   c.add(jsp, BorderLayout.CENTER);
   f.setSize(250, 250);
   f.show();
 }
 public static void main(String args[]) {
   new TreeIt();
 }

}



 </source>
   
  
 
  



Display user object in a tree

   <source lang="java">
 

/* From http://java.sun.ru/docs/books/tutorial/index.html */ /*

* Copyright (c) 2006 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:
*
* -Redistribution of source code must retain the above copyright notice, this
*  list of conditions and the following disclaimer.
*
* -Redistribution 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, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed, licensed or intended
* for use in the design, construction, operation or maintenance of any
* nuclear facility.
*/

/**

* 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.Dimension; import java.awt.GridLayout; import java.io.IOException; import java.net.URL; 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.UIManager; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreeSelectionModel; public class TreeDemo extends JPanel

                     implements TreeSelectionListener {
   private JEditorPane htmlPane;
   private JTree tree;
   private URL helpURL;
   private static boolean DEBUG = false;
   //Optionally play with line styles.  Possible values are
   //"Angled" (the default), "Horizontal", and "None".
   private static boolean playWithLineStyle = false;
   private static String lineStyle = "Horizontal";
   
   //Optionally set the look and feel.
   private static boolean useSystemLookAndFeel = false;
   public TreeDemo() {
       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);
       //Listen for when the selection changes.
       tree.addTreeSelectionListener(this);
       if (playWithLineStyle) {
           System.out.println("line style = " + lineStyle);
           tree.putClientProperty("JTree.lineStyle", lineStyle);
       }
       //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 = TreeDemo.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 = TreeDemo.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);
   }
       
   /**
    * Create the GUI and show it.  For thread safety,
    * this method should be invoked from the
    * event-dispatching thread.
    */
   private static void createAndShowGUI() {
       if (useSystemLookAndFeel) {
           try {
               UIManager.setLookAndFeel(
                   UIManager.getSystemLookAndFeelClassName());
           } catch (Exception e) {
               System.err.println("Couldn"t use system look and feel.");
           }
       }
       //Make sure we have nice window decorations.
       JFrame.setDefaultLookAndFeelDecorated(true);
       //Create and set up the window.
       JFrame frame = new JFrame("TreeDemo");
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       //Create and set up the content pane.
       TreeDemo newContentPane = new TreeDemo();
       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();
           }
       });
   }

}



 </source>
   
  
 
  



DnD (drag and drop)JTree code

   <source lang="java">
 

/* Java Swing, 2nd Edition By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole ISBN: 0-596-00408-7 Publisher: O"Reilly

  • /

// TreeDragTest.java //A simple starting point for testing the DnD JTree code. // import java.awt.BorderLayout; import java.awt.Color; import java.awt.Graphics; import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.dnd.Autoscroll; import java.awt.dnd.DnDConstants; import java.awt.dnd.DragGestureEvent; import java.awt.dnd.DragGestureListener; import java.awt.dnd.DragGestureRecognizer; import java.awt.dnd.DragSource; import java.awt.dnd.DragSourceDragEvent; import java.awt.dnd.DragSourceDropEvent; import java.awt.dnd.DragSourceEvent; import java.awt.dnd.DragSourceListener; import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetContext; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetListener; import java.io.IOException; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; public class TreeDragTest extends JFrame {

 TreeDragSource ds;
 TreeDropTarget dt;
 JTree tree;
 public TreeDragTest() {
   super("Rearrangeable Tree");
   setSize(300, 200);
   setDefaultCloseOperation(EXIT_ON_CLOSE);
   // If you want autoscrolling, use this line:
   tree = new AutoScrollingJTree();
   // Otherwise, use this line:
   //tree = new JTree();
   getContentPane().add(new JScrollPane(tree), BorderLayout.CENTER);
   // If we only support move operations...
   //ds = new TreeDragSource(tree, DnDConstants.ACTION_MOVE);
   ds = new TreeDragSource(tree, DnDConstants.ACTION_COPY_OR_MOVE);
   dt = new TreeDropTarget(tree);
   setVisible(true);
 }
 public class AutoScrollingJTree extends JTree implements Autoscroll {
   private int margin = 12;
   public AutoScrollingJTree() {
     super();
   }
   public void autoscroll(Point p) {
     int realrow = getRowForLocation(p.x, p.y);
     Rectangle outer = getBounds();
     realrow = (p.y + outer.y <= margin ? realrow < 1 ? 0 : realrow - 1
         : realrow < getRowCount() - 1 ? realrow + 1 : realrow);
     scrollRowToVisible(realrow);
   }
   public Insets getAutoscrollInsets() {
     Rectangle outer = getBounds();
     Rectangle inner = getParent().getBounds();
     return new Insets(inner.y - outer.y + margin, inner.x - outer.x
         + margin, outer.height - inner.height - inner.y + outer.y
         + margin, outer.width - inner.width - inner.x + outer.x
         + margin);
   }
   // Use this method if you want to see the boundaries of the
   // autoscroll active region
   public void paintComponent(Graphics g) {
     super.paintComponent(g);
     Rectangle outer = getBounds();
     Rectangle inner = getParent().getBounds();
     g.setColor(Color.red);
     g.drawRect(-outer.x + 12, -outer.y + 12, inner.width - 24,
         inner.height - 24);
   }
 }
 public static void main(String args[]) {
   new TreeDragTest();
 }

} //TreeDragSource.java //A drag source wrapper for a JTree. This class can be used to make //a rearrangeable DnD tree with the TransferableTreeNode class as the //transfer data type. class TreeDragSource implements DragSourceListener, DragGestureListener {

 DragSource source;
 DragGestureRecognizer recognizer;
 TransferableTreeNode transferable;
 DefaultMutableTreeNode oldNode;
 JTree sourceTree;
 public TreeDragSource(JTree tree, int actions) {
   sourceTree = tree;
   source = new DragSource();
   recognizer = source.createDefaultDragGestureRecognizer(sourceTree,
       actions, this);
 }
 /*
  * Drag Gesture Handler
  */
 public void dragGestureRecognized(DragGestureEvent dge) {
   TreePath path = sourceTree.getSelectionPath();
   if ((path == null) || (path.getPathCount() <= 1)) {
     // We can"t move the root node or an empty selection
     return;
   }
   oldNode = (DefaultMutableTreeNode) path.getLastPathComponent();
   transferable = new TransferableTreeNode(path);
   source.startDrag(dge, DragSource.DefaultMoveNoDrop, transferable, this);
   // If you support dropping the node anywhere, you should probably
   // start with a valid move cursor:
   //source.startDrag(dge, DragSource.DefaultMoveDrop, transferable,
   // this);
 }
 /*
  * Drag Event Handlers
  */
 public void dragEnter(DragSourceDragEvent dsde) {
 }
 public void dragExit(DragSourceEvent dse) {
 }
 public void dragOver(DragSourceDragEvent dsde) {
 }
 public void dropActionChanged(DragSourceDragEvent dsde) {
   System.out.println("Action: " + dsde.getDropAction());
   System.out.println("Target Action: " + dsde.getTargetActions());
   System.out.println("User Action: " + dsde.getUserAction());
 }
 public void dragDropEnd(DragSourceDropEvent dsde) {
   /*
    * to support move or copy, we have to check which occurred:
    */
   System.out.println("Drop Action: " + dsde.getDropAction());
   if (dsde.getDropSuccess()
       && (dsde.getDropAction() == DnDConstants.ACTION_MOVE)) {
     ((DefaultTreeModel) sourceTree.getModel())
         .removeNodeFromParent(oldNode);
   }
   /*
    * to support move only... if (dsde.getDropSuccess()) {
    * ((DefaultTreeModel)sourceTree.getModel()).removeNodeFromParent(oldNode); }
    */
 }

} //TreeDropTarget.java //A quick DropTarget that"s looking for drops from draggable JTrees. // class TreeDropTarget implements DropTargetListener {

 DropTarget target;
 JTree targetTree;
 public TreeDropTarget(JTree tree) {
   targetTree = tree;
   target = new DropTarget(targetTree, this);
 }
 /*
  * Drop Event Handlers
  */
 private TreeNode getNodeForEvent(DropTargetDragEvent dtde) {
   Point p = dtde.getLocation();
   DropTargetContext dtc = dtde.getDropTargetContext();
   JTree tree = (JTree) dtc.getComponent();
   TreePath path = tree.getClosestPathForLocation(p.x, p.y);
   return (TreeNode) path.getLastPathComponent();
 }
 public void dragEnter(DropTargetDragEvent dtde) {
   TreeNode node = getNodeForEvent(dtde);
   if (node.isLeaf()) {
     dtde.rejectDrag();
   } else {
     // start by supporting move operations
     //dtde.acceptDrag(DnDConstants.ACTION_MOVE);
     dtde.acceptDrag(dtde.getDropAction());
   }
 }
 public void dragOver(DropTargetDragEvent dtde) {
   TreeNode node = getNodeForEvent(dtde);
   if (node.isLeaf()) {
     dtde.rejectDrag();
   } else {
     // start by supporting move operations
     //dtde.acceptDrag(DnDConstants.ACTION_MOVE);
     dtde.acceptDrag(dtde.getDropAction());
   }
 }
 public void dragExit(DropTargetEvent dte) {
 }
 public void dropActionChanged(DropTargetDragEvent dtde) {
 }
 public void drop(DropTargetDropEvent dtde) {
   Point pt = dtde.getLocation();
   DropTargetContext dtc = dtde.getDropTargetContext();
   JTree tree = (JTree) dtc.getComponent();
   TreePath parentpath = tree.getClosestPathForLocation(pt.x, pt.y);
   DefaultMutableTreeNode parent = (DefaultMutableTreeNode) parentpath
       .getLastPathComponent();
   if (parent.isLeaf()) {
     dtde.rejectDrop();
     return;
   }
   try {
     Transferable tr = dtde.getTransferable();
     DataFlavor[] flavors = tr.getTransferDataFlavors();
     for (int i = 0; i < flavors.length; i++) {
       if (tr.isDataFlavorSupported(flavors[i])) {
         dtde.acceptDrop(dtde.getDropAction());
         TreePath p = (TreePath) tr.getTransferData(flavors[i]);
         DefaultMutableTreeNode node = (DefaultMutableTreeNode) p
             .getLastPathComponent();
         DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
         model.insertNodeInto(node, parent, 0);
         dtde.dropComplete(true);
         return;
       }
     }
     dtde.rejectDrop();
   } catch (Exception e) {
     e.printStackTrace();
     dtde.rejectDrop();
   }
 }

} //TransferableTreeNode.java //A Transferable TreePath to be used with Drag & Drop applications. // class TransferableTreeNode implements Transferable {

 public static DataFlavor TREE_PATH_FLAVOR = new DataFlavor(TreePath.class,
     "Tree Path");
 DataFlavor flavors[] = { TREE_PATH_FLAVOR };
 TreePath path;
 public TransferableTreeNode(TreePath tp) {
   path = tp;
 }
 public synchronized DataFlavor[] getTransferDataFlavors() {
   return flavors;
 }
 public boolean isDataFlavorSupported(DataFlavor flavor) {
   return (flavor.getRepresentationClass() == TreePath.class);
 }
 public synchronized Object getTransferData(DataFlavor flavor)
     throws UnsupportedFlavorException, IOException {
   if (isDataFlavorSupported(flavor)) {
     return (Object) path;
   } else {
     throw new UnsupportedFlavorException(flavor);
   }
 }

}


 </source>
   
  
 
  



Drag and drop of a group of files into a tree

   <source lang="java">
 

import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.io.File; import java.io.IOException; import java.util.Iterator; import java.util.List; import javax.swing.JComponent; import javax.swing.JTree; import javax.swing.TransferHandler; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; public class MyTree extends JTree {

 public MyTree() {
   super();
   setDragEnabled(false);
   setTransferHandler(new FSTransfer());
 }

} class FSTransfer extends TransferHandler {

 public boolean importData(JComponent comp, Transferable t) {
   if (!(comp instanceof MyTree)) {
     return false;
   }
   if (!t.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
     return false;
   }
   MyTree tree = (MyTree) comp;
   DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
   DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();
   try {
     List data = (List) t.getTransferData(DataFlavor.javaFileListFlavor);
     Iterator i = data.iterator();
     while (i.hasNext()) {
       File f = (File) i.next();
       root.add(new DefaultMutableTreeNode(f.getName()));
     }
     model.reload();
     return true;
   } catch (Exception ioe) {
     System.out.println(ioe);
   }
   return false;
 }
 public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
   if (comp instanceof MyTree) {
     for (int i = 0; i < transferFlavors.length; i++) {
       if (!transferFlavors[i].equals(DataFlavor.javaFileListFlavor)) {
         return false;
       }
     }
     return true;
   }
   return false;
 }

}


 </source>
   
  
 
  



Enabling and Disabling Multiple Selections in a JTree Component

   <source lang="java">
 

import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.tree.TreeSelectionModel; public class TreeSelectionOption {

 public static void main(String[] argv) {
   JTree tree = new JTree();
   tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
   tree.getSelectionModel().setSelectionMode(TreeSelectionModel.CONTIGUOUS_TREE_SELECTION);
   tree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
   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>
   
  
 
  



Expand All for a tree path

   <source lang="java">

/*

*  soapUI, copyright (C) 2004-2009 eviware.ru 
*
*  soapUI is free software; you can redistribute it and/or modify it under the 
*  terms of version 2.1 of the GNU Lesser General Public License as published by 
*  the Free Software Foundation.
*
*  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
*  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
*  See the GNU Lesser General Public License for more details at gnu.org.
*/

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

 public static void expandAll(JTree tree, TreePath parent, boolean expand) {
   // Traverse children
   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, expand);
     }
   }
   // Expansion or collapse must be done bottom-up
   if (expand) {
     tree.expandPath(parent);
   } else {
     tree.collapsePath(parent);
   }
 }

}

 </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>
   
  
 
  



Expansion and Collapse Events in a JTree are fired before a node is expanded or collapsed can be vetoed, thereby preventing the operation.

   <source lang="java">
 

import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.event.TreeExpansionEvent; import javax.swing.event.TreeExpansionListener; import javax.swing.event.TreeWillExpandListener; import javax.swing.tree.ExpandVetoException; import javax.swing.tree.TreePath; public class Main {

 public static void main() {
   JTree tree = new JTree();
   tree.addTreeWillExpandListener(new MyTreeWillExpandListener());
   tree.addTreeExpansionListener(new MyTreeExpansionListener());
   JFrame f = new JFrame();
   f.add(new JScrollPane(tree));
   f.setSize(300, 300);
   f.setVisible(true);
 }

} class MyTreeWillExpandListener implements TreeWillExpandListener {

 public void treeWillExpand(TreeExpansionEvent evt) throws ExpandVetoException {
   JTree tree = (JTree) evt.getSource();
   TreePath path = evt.getPath();
   boolean veto = false;
   if (veto) {
     throw new ExpandVetoException(evt);
   }
 }
 public void treeWillCollapse(TreeExpansionEvent evt) throws ExpandVetoException {
   JTree tree = (JTree) evt.getSource();
   TreePath path = evt.getPath();
   boolean veto = false;
   if (veto) {
     throw new ExpandVetoException(evt);
   }
 }

} class MyTreeExpansionListener implements TreeExpansionListener {

 public void treeExpanded(TreeExpansionEvent evt) {
   JTree tree = (JTree) evt.getSource();
   TreePath path = evt.getPath();
   System.out.println("treeExpanded");
 }
 public void treeCollapsed(TreeExpansionEvent evt) {
   JTree tree = (JTree) evt.getSource();
   TreePath path = evt.getPath();
   System.out.println("treeCollapsed");
 }

}


 </source>
   
  
 
  



File folder Tree with icons

   <source lang="java">
 

/* Swing, Second Edition by Matthew Robinson, Pavel Vorobiev

  • /

import java.awt.*; import java.awt.event.*; import java.io.*; import java.util.*; import javax.swing.*; import javax.swing.tree.*; import javax.swing.event.*; public class FileTree1

 extends JFrame 

{

 public static final ImageIcon ICON_COMPUTER = 
   new ImageIcon("computer.gif");
 public static final ImageIcon ICON_DISK = 
   new ImageIcon("disk.gif");
 public static final ImageIcon ICON_FOLDER = 
   new ImageIcon("folder.gif");
 public static final ImageIcon ICON_EXPANDEDFOLDER = 
   new ImageIcon("expandedfolder.gif");
 protected JTree  m_tree;
 protected DefaultTreeModel m_model;
 protected JTextField m_display;
 public FileTree1()
 {
   super("Directories Tree");
   setSize(400, 300);
   DefaultMutableTreeNode top = new DefaultMutableTreeNode(
     new IconData(ICON_COMPUTER, null, "Computer"));
   DefaultMutableTreeNode node;
   File[] roots = File.listRoots();
   for (int k=0; k<roots.length; k++)
   {
     node = new DefaultMutableTreeNode(new IconData(ICON_DISK, 
       null, new FileNode(roots[k])));
     top.add(node);
                       node.add( new DefaultMutableTreeNode(new Boolean(true)));
   }
   m_model = new DefaultTreeModel(top);
   m_tree = new JTree(m_model);
               m_tree.putClientProperty("JTree.lineStyle", "Angled");
   TreeCellRenderer renderer = new 
     IconCellRenderer();
   m_tree.setCellRenderer(renderer);
   m_tree.addTreeExpansionListener(new 
     DirExpansionListener());
   m_tree.addTreeSelectionListener(new 
     DirSelectionListener());
   m_tree.getSelectionModel().setSelectionMode(
     TreeSelectionModel.SINGLE_TREE_SELECTION); 
   m_tree.setShowsRootHandles(true); 
   m_tree.setEditable(false);
   JScrollPane s = new JScrollPane();
   s.getViewport().add(m_tree);
   getContentPane().add(s, BorderLayout.CENTER);
   m_display = new JTextField();
   m_display.setEditable(false);
   getContentPane().add(m_display, BorderLayout.NORTH);
   WindowListener wndCloser = new WindowAdapter()
   {
     public void windowClosing(WindowEvent e) 
     {
       System.exit(0);
     }
   };
   addWindowListener(wndCloser);
   
   setVisible(true);
 }
 DefaultMutableTreeNode getTreeNode(TreePath path)
 {
   return (DefaultMutableTreeNode)(path.getLastPathComponent());
 }
 FileNode getFileNode(DefaultMutableTreeNode node)
 {
   if (node == null)
     return null;
   Object obj = node.getUserObject();
   if (obj instanceof IconData)
     obj = ((IconData)obj).getObject();
   if (obj instanceof FileNode)
     return (FileNode)obj;
   else
     return null;
 }
   // Make sure expansion is threaded and updating the tree model
   // only occurs within the event dispatching thread.
   class DirExpansionListener implements TreeExpansionListener
   {
       public void treeExpanded(TreeExpansionEvent event)
       {
           final DefaultMutableTreeNode node = getTreeNode(
               event.getPath());
           final FileNode fnode = getFileNode(node);
           Thread runner = new Thread() 
           {
             public void run() 
             {
               if (fnode != null && fnode.expand(node)) 
               {
                 Runnable runnable = new Runnable() 
                 {
                   public void run() 
                   {
                      m_model.reload(node);
                   }
                 };
                 SwingUtilities.invokeLater(runnable);
               }
             }
           };
           runner.start();
       }
       public void treeCollapsed(TreeExpansionEvent event) {}
   }
 class DirSelectionListener 
   implements TreeSelectionListener 
 {
   public void valueChanged(TreeSelectionEvent event)
   {
     DefaultMutableTreeNode node = getTreeNode(
       event.getPath());
     FileNode fnode = getFileNode(node);
     if (fnode != null)
       m_display.setText(fnode.getFile().
         getAbsolutePath());
     else
       m_display.setText("");
   }
 }
 public static void main(String argv[]) 
 {
   new FileTree1();
 }

} class IconCellRenderer

 extends    JLabel 
 implements TreeCellRenderer

{

 protected Color m_textSelectionColor;
 protected Color m_textNonSelectionColor;
 protected Color m_bkSelectionColor;
 protected Color m_bkNonSelectionColor;
 protected Color m_borderSelectionColor;
 protected boolean m_selected;
 public IconCellRenderer()
 {
   super();
   m_textSelectionColor = UIManager.getColor(
     "Tree.selectionForeground");
   m_textNonSelectionColor = UIManager.getColor(
     "Tree.textForeground");
   m_bkSelectionColor = UIManager.getColor(
     "Tree.selectionBackground");
   m_bkNonSelectionColor = UIManager.getColor(
     "Tree.textBackground");
   m_borderSelectionColor = UIManager.getColor(
     "Tree.selectionBorderColor");
   setOpaque(false);
 }
 public Component getTreeCellRendererComponent(JTree tree, 
   Object value, boolean sel, boolean expanded, boolean leaf, 
   int row, boolean hasFocus) 
   
 {
   DefaultMutableTreeNode node = 
     (DefaultMutableTreeNode)value;
   Object obj = node.getUserObject();
   setText(obj.toString());
               if (obj instanceof Boolean)
                 setText("Retrieving data...");
   if (obj instanceof IconData)
   {
     IconData idata = (IconData)obj;
     if (expanded)
       setIcon(idata.getExpandedIcon());
     else
       setIcon(idata.getIcon());
   }
   else
     setIcon(null);
   setFont(tree.getFont());
   setForeground(sel ? m_textSelectionColor : 
     m_textNonSelectionColor);
   setBackground(sel ? m_bkSelectionColor : 
     m_bkNonSelectionColor);
   m_selected = sel;
   return this;
 }
   
 public void paintComponent(Graphics g) 
 {
   Color bColor = getBackground();
   Icon icon = getIcon();
   g.setColor(bColor);
   int offset = 0;
   if(icon != null && getText() != null) 
     offset = (icon.getIconWidth() + getIconTextGap());
   g.fillRect(offset, 0, getWidth() - 1 - offset,
     getHeight() - 1);
   
   if (m_selected) 
   {
     g.setColor(m_borderSelectionColor);
     g.drawRect(offset, 0, getWidth()-1-offset, getHeight()-1);
   }
   super.paintComponent(g);
   }

} class IconData {

 protected Icon   m_icon;
 protected Icon   m_expandedIcon;
 protected Object m_data;
 public IconData(Icon icon, Object data)
 {
   m_icon = icon;
   m_expandedIcon = null;
   m_data = data;
 }
 public IconData(Icon icon, Icon expandedIcon, Object data)
 {
   m_icon = icon;
   m_expandedIcon = expandedIcon;
   m_data = data;
 }
 public Icon getIcon() 
 { 
   return m_icon;
 }
 public Icon getExpandedIcon() 
 { 
   return m_expandedIcon!=null ? m_expandedIcon : m_icon;
 }
 public Object getObject() 
 { 
   return m_data;
 }
 public String toString() 
 { 
   return m_data.toString();
 }

} class FileNode {

 protected File m_file;
 public FileNode(File file)
 {
   m_file = file;
 }
 public File getFile() 
 { 
   return m_file;
 }
 public String toString() 
 { 
   return m_file.getName().length() > 0 ? m_file.getName() : 
     m_file.getPath();
 }
 public boolean expand(DefaultMutableTreeNode parent)
 {
   DefaultMutableTreeNode flag = 
     (DefaultMutableTreeNode)parent.getFirstChild();
   if (flag==null)    // No flag
     return false;
   Object obj = flag.getUserObject();
   if (!(obj instanceof Boolean))
     return false;      // Already expanded
   parent.removeAllChildren();  // Remove Flag
   File[] files = listFiles();
   if (files == null)
     return true;
   Vector v = new Vector();
   for (int k=0; k<files.length; k++)
   {
     File f = files[k];
     if (!(f.isDirectory()))
       continue;
     FileNode newNode = new FileNode(f);
     
     boolean isAdded = false;
     for (int i=0; i<v.size(); i++)
     {
       FileNode nd = (FileNode)v.elementAt(i);
       if (newNode.rupareTo(nd) < 0)
       {
         v.insertElementAt(newNode, i);
         isAdded = true;
         break;
       }
     }
     if (!isAdded)
       v.addElement(newNode);
   }
   for (int i=0; i<v.size(); i++)
   {
     FileNode nd = (FileNode)v.elementAt(i);
     IconData idata = new IconData(FileTree1.ICON_FOLDER, 
       FileTree1.ICON_EXPANDEDFOLDER, nd);
     DefaultMutableTreeNode node = new 
       DefaultMutableTreeNode(idata);
     parent.add(node);
       
     if (nd.hasSubDirs())
       node.add(new DefaultMutableTreeNode( 
         new Boolean(true) ));
   }
   return true;
 }
 public boolean hasSubDirs()
 {
   File[] files = listFiles();
   if (files == null)
     return false;
   for (int k=0; k<files.length; k++)
   {
     if (files[k].isDirectory())
       return true;
   }
   return false;
 }
 
 public int compareTo(FileNode toCompare)
 { 
   return  m_file.getName().rupareToIgnoreCase(
     toCompare.m_file.getName() ); 
 }
 protected File[] listFiles()
 {
   if (!m_file.isDirectory())
     return null;
   try
   {
     return m_file.listFiles();
   }
   catch (Exception ex)
   {
     JOptionPane.showMessageDialog(null, 
       "Error reading directory "+m_file.getAbsolutePath(),
       "Warning", JOptionPane.WARNING_MESSAGE);
     return null;
   }
 }

}


 </source>
   
  
 
  



File System Tree

   <source lang="java">
 

import java.io.File; import java.util.Iterator; import java.util.Vector; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTextArea; import javax.swing.JTree; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; public class FileTreeFrame extends JFrame {

 private JTree fileTree;
 private FileSystemModel fileSystemModel;
 private JTextArea fileDetailsTextArea = new JTextArea();
 public FileTreeFrame(String directory) {
   super("JTree FileSystem Viewer");
   fileDetailsTextArea.setEditable(false);
   fileSystemModel = new FileSystemModel(new File(directory));
   fileTree = new JTree(fileSystemModel);
   fileTree.setEditable(true);
   fileTree.addTreeSelectionListener(new TreeSelectionListener() {
     public void valueChanged(TreeSelectionEvent event) {
       File file = (File) fileTree.getLastSelectedPathComponent();
       fileDetailsTextArea.setText(getFileDetails(file));
     }
   });
   JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, new JScrollPane(
       fileTree), new JScrollPane(fileDetailsTextArea));
   getContentPane().add(splitPane);
   setDefaultCloseOperation(EXIT_ON_CLOSE);
   setSize(640, 480);
   setVisible(true);
 }
 private String getFileDetails(File file) {
   if (file == null)
     return "";
   StringBuffer buffer = new StringBuffer();
   buffer.append("Name: " + file.getName() + "\n");
   buffer.append("Path: " + file.getPath() + "\n");
   buffer.append("Size: " + file.length() + "\n");
   return buffer.toString();
 }
 public static void main(String args[]) {
   new FileTreeFrame("c:\\");
 }

} class FileSystemModel implements TreeModel {

 private File root;
 private Vector listeners = new Vector();
 public FileSystemModel(File rootDirectory) {
   root = rootDirectory;
 }
 public Object getRoot() {
   return root;
 }
 public Object getChild(Object parent, int index) {
   File directory = (File) parent;
   String[] children = directory.list();
   return new TreeFile(directory, children[index]);
 }
 public int getChildCount(Object parent) {
   File file = (File) parent;
   if (file.isDirectory()) {
     String[] fileList = file.list();
     if (fileList != null)
       return file.list().length;
   }
   return 0;
 }
 public boolean isLeaf(Object node) {
   File file = (File) node;
   return file.isFile();
 }
 public int getIndexOfChild(Object parent, Object child) {
   File directory = (File) parent;
   File file = (File) child;
   String[] children = directory.list();
   for (int i = 0; i < children.length; i++) {
     if (file.getName().equals(children[i])) {
       return i;
     }
   }
   return -1;
 }
 public void valueForPathChanged(TreePath path, Object value) {
   File oldFile = (File) path.getLastPathComponent();
   String fileParentPath = oldFile.getParent();
   String newFileName = (String) value;
   File targetFile = new File(fileParentPath, newFileName);
   oldFile.renameTo(targetFile);
   File parent = new File(fileParentPath);
   int[] changedChildrenIndices = { getIndexOfChild(parent, targetFile) };
   Object[] changedChildren = { targetFile };
   fireTreeNodesChanged(path.getParentPath(), changedChildrenIndices, changedChildren);
 }
 private void fireTreeNodesChanged(TreePath parentPath, int[] indices, Object[] children) {
   TreeModelEvent event = new TreeModelEvent(this, parentPath, indices, children);
   Iterator iterator = listeners.iterator();
   TreeModelListener listener = null;
   while (iterator.hasNext()) {
     listener = (TreeModelListener) iterator.next();
     listener.treeNodesChanged(event);
   }
 }
 public void addTreeModelListener(TreeModelListener listener) {
   listeners.add(listener);
 }
 public void removeTreeModelListener(TreeModelListener listener) {
   listeners.remove(listener);
 }
 private class TreeFile extends File {
   public TreeFile(File parent, String child) {
     super(parent, child);
   }
   public String toString() {
     return getName();
   }
 }

}


 </source>
   
  
 
  



File Tree with Popup Menu

   <source lang="java">
 

import java.awt.*; import java.awt.event.*; import java.io.*; import java.util.*; import java.text.SimpleDateFormat; import javax.swing.*; import javax.swing.tree.*; import javax.swing.event.*; public class FileTree2

 extends JFrame 

{

 public static final ImageIcon ICON_COMPUTER = 
   new ImageIcon("computer.gif");
 public static final ImageIcon ICON_DISK = 
   new ImageIcon("disk.gif");
 public static final ImageIcon ICON_FOLDER = 
   new ImageIcon("folder.gif");
 public static final ImageIcon ICON_EXPANDEDFOLDER = 
   new ImageIcon("expandedfolder.gif");
 protected JTree  m_tree;
 protected DefaultTreeModel m_model;
 protected JTextField m_display;

// NEW

 protected JPopupMenu m_popup;
 protected Action m_action;
 protected TreePath m_clickedPath;
 public FileTree2()
 {
   super("Directories Tree [Popup Menus]");
   setSize(400, 300);
   DefaultMutableTreeNode top = new DefaultMutableTreeNode(
     new IconData(ICON_COMPUTER, null, "Computer"));
   DefaultMutableTreeNode node;
   File[] roots = File.listRoots();
   for (int k=0; k<roots.length; k++)
   {
     node = new DefaultMutableTreeNode(new IconData(ICON_DISK, 
       null, new FileNode(roots[k])));
     top.add(node);
     node.add(new DefaultMutableTreeNode( new Boolean(true) ));
   }
   m_model = new DefaultTreeModel(top);
   m_tree = new JTree(m_model);
               m_tree.putClientProperty("JTree.lineStyle", "Angled");
   TreeCellRenderer renderer = new 
     IconCellRenderer();
   m_tree.setCellRenderer(renderer);
   m_tree.addTreeExpansionListener(new 
     DirExpansionListener());
   m_tree.addTreeSelectionListener(new 
     DirSelectionListener());
   m_tree.getSelectionModel().setSelectionMode(
     TreeSelectionModel.SINGLE_TREE_SELECTION); 
   m_tree.setShowsRootHandles(true); 
   m_tree.setEditable(false);
   JScrollPane s = new JScrollPane();
   s.getViewport().add(m_tree);
   getContentPane().add(s, BorderLayout.CENTER);
   m_display = new JTextField();
   m_display.setEditable(false);
   getContentPane().add(m_display, BorderLayout.NORTH);

// NEW

   m_popup = new JPopupMenu();
   m_action = new AbstractAction() 
   { 
     public void actionPerformed(ActionEvent e)
     {
       if (m_clickedPath==null)
         return;
       if (m_tree.isExpanded(m_clickedPath))
         m_tree.collapsePath(m_clickedPath);
       else
         m_tree.expandPath(m_clickedPath);
     }
   };
   m_popup.add(m_action);
   m_popup.addSeparator();
   Action a1 = new AbstractAction("Delete") 
   { 
     public void actionPerformed(ActionEvent e)
     {
                               m_tree.repaint();
       JOptionPane.showMessageDialog(FileTree2.this, 
         "Delete option is not implemented",
         "Info", JOptionPane.INFORMATION_MESSAGE);
     }
   };
   m_popup.add(a1);
   Action a2 = new AbstractAction("Rename") 
   { 
     public void actionPerformed(ActionEvent e)
     {
                               m_tree.repaint();
       JOptionPane.showMessageDialog(FileTree2.this, 
         "Rename option is not implemented",
         "Info", JOptionPane.INFORMATION_MESSAGE);
     }
   };
   m_popup.add(a2);
   m_tree.add(m_popup);
   m_tree.addMouseListener(new PopupTrigger());
   WindowListener wndCloser = new WindowAdapter()
   {
     public void windowClosing(WindowEvent e) 
     {
       System.exit(0);
     }
   };
   addWindowListener(wndCloser);
   
   setVisible(true);
 }
 DefaultMutableTreeNode getTreeNode(TreePath path)
 {
   return (DefaultMutableTreeNode)(path.getLastPathComponent());
 }
 FileNode getFileNode(DefaultMutableTreeNode node)
 {
   if (node == null)
     return null;
   Object obj = node.getUserObject();
   if (obj instanceof IconData)
     obj = ((IconData)obj).getObject();
   if (obj instanceof FileNode)
     return (FileNode)obj;
   else
     return null;
 }

// NEW

 class PopupTrigger extends MouseAdapter
 {
   public void mouseReleased(MouseEvent e)
   {
     if (e.isPopupTrigger())
     {
       int x = e.getX();
       int y = e.getY();
       TreePath path = m_tree.getPathForLocation(x, y);
       if (path != null)
       {
         if (m_tree.isExpanded(path))
           m_action.putValue(Action.NAME, "Collapse");
         else
           m_action.putValue(Action.NAME, "Expand");
         m_popup.show(m_tree, x, y);
         m_clickedPath = path;
       }
     }
   }
 }
   // Make sure expansion is threaded and updating the tree model
   // only occurs within the event dispatching thread.
   class DirExpansionListener implements TreeExpansionListener
   {
       public void treeExpanded(TreeExpansionEvent event)
       {
           final DefaultMutableTreeNode node = getTreeNode(
               event.getPath());
           final FileNode fnode = getFileNode(node);
           Thread runner = new Thread() 
           {
             public void run() 
             {
               if (fnode != null && fnode.expand(node)) 
               {
                 Runnable runnable = new Runnable() 
                 {
                   public void run() 
                   {
                      m_model.reload(node);
                   }
                 };
                 SwingUtilities.invokeLater(runnable);
               }
             }
           };
           runner.start();
       }
       public void treeCollapsed(TreeExpansionEvent event) {}
   }
 class DirSelectionListener 
   implements TreeSelectionListener 
 {
   public void valueChanged(TreeSelectionEvent event)
   {
     DefaultMutableTreeNode node = getTreeNode(
       event.getPath());
     FileNode fnode = getFileNode(node);
     if (fnode != null)
       m_display.setText(fnode.getFile().
         getAbsolutePath());
     else
       m_display.setText("");
   }
 }
 public static void main(String argv[]) 
 {
   new FileTree2();
 }

} class IconCellRenderer

 extends    JLabel 
 implements TreeCellRenderer

{

 protected Color m_textSelectionColor;
 protected Color m_textNonSelectionColor;
 protected Color m_bkSelectionColor;
 protected Color m_bkNonSelectionColor;
 protected Color m_borderSelectionColor;
 protected boolean m_selected;
 public IconCellRenderer()
 {
   super();
   m_textSelectionColor = UIManager.getColor(
     "Tree.selectionForeground");
   m_textNonSelectionColor = UIManager.getColor(
     "Tree.textForeground");
   m_bkSelectionColor = UIManager.getColor(
     "Tree.selectionBackground");
   m_bkNonSelectionColor = UIManager.getColor(
     "Tree.textBackground");
   m_borderSelectionColor = UIManager.getColor(
     "Tree.selectionBorderColor");
   setOpaque(false);
 }
 public Component getTreeCellRendererComponent(JTree tree, 
   Object value, boolean sel, boolean expanded, boolean leaf, 
   int row, boolean hasFocus) 
   
 {
   DefaultMutableTreeNode node = 
     (DefaultMutableTreeNode)value;
   Object obj = node.getUserObject();
   setText(obj.toString());
               if (obj instanceof Boolean)
                 setText("Retrieving data...");
   if (obj instanceof IconData)
   {
     IconData idata = (IconData)obj;
     if (expanded)
       setIcon(idata.getExpandedIcon());
     else
       setIcon(idata.getIcon());
   }
   else
     setIcon(null);
   setFont(tree.getFont());
   setForeground(sel ? m_textSelectionColor : 
     m_textNonSelectionColor);
   setBackground(sel ? m_bkSelectionColor : 
     m_bkNonSelectionColor);
   m_selected = sel;
   return this;
 }
   
 public void paintComponent(Graphics g) 
 {
   Color bColor = getBackground();
   Icon icon = getIcon();
   g.setColor(bColor);
   int offset = 0;
   if(icon != null && getText() != null) 
     offset = (icon.getIconWidth() + getIconTextGap());
   g.fillRect(offset, 0, getWidth() - 1 - offset,
     getHeight() - 1);
   
   if (m_selected) 
   {
     g.setColor(m_borderSelectionColor);
     g.drawRect(offset, 0, getWidth()-1-offset, getHeight()-1);
   }
   super.paintComponent(g);
   }

} class IconData {

 protected Icon   m_icon;
 protected Icon   m_expandedIcon;
 protected Object m_data;
 public IconData(Icon icon, Object data)
 {
   m_icon = icon;
   m_expandedIcon = null;
   m_data = data;
 }
 public IconData(Icon icon, Icon expandedIcon, Object data)
 {
   m_icon = icon;
   m_expandedIcon = expandedIcon;
   m_data = data;
 }
 public Icon getIcon() 
 { 
   return m_icon;
 }
 public Icon getExpandedIcon() 
 { 
   return m_expandedIcon!=null ? m_expandedIcon : m_icon;
 }
 public Object getObject() 
 { 
   return m_data;
 }
 public String toString() 
 { 
   return m_data.toString();
 }

} class FileNode {

 protected File m_file;
 public FileNode(File file)
 {
   m_file = file;
 }
 public File getFile() 
 { 
   return m_file;
 }
 public String toString() 
 { 
   return m_file.getName().length() > 0 ? m_file.getName() : 
     m_file.getPath();
 }
 public boolean expand(DefaultMutableTreeNode parent)
 {
   DefaultMutableTreeNode flag = 
     (DefaultMutableTreeNode)parent.getFirstChild();
   if (flag==null)    // No flag
     return false;
   Object obj = flag.getUserObject();
   if (!(obj instanceof Boolean))
     return false;      // Already expanded
   parent.removeAllChildren();  // Remove Flag
   File[] files = listFiles();
   if (files == null)
     return true;
   Vector v = new Vector();
   for (int k=0; k<files.length; k++)
   {
     File f = files[k];
     if (!(f.isDirectory()))
       continue;
     FileNode newNode = new FileNode(f);
     
     boolean isAdded = false;
     for (int i=0; i<v.size(); i++)
     {
       FileNode nd = (FileNode)v.elementAt(i);
       if (newNode.rupareTo(nd) < 0)
       {
         v.insertElementAt(newNode, i);
         isAdded = true;
         break;
       }
     }
     if (!isAdded)
       v.addElement(newNode);
   }
   for (int i=0; i<v.size(); i++)
   {
     FileNode nd = (FileNode)v.elementAt(i);
     IconData idata = new IconData(FileTree2.ICON_FOLDER, 
       FileTree2.ICON_EXPANDEDFOLDER, nd);
     DefaultMutableTreeNode node = new 
       DefaultMutableTreeNode(idata);
     parent.add(node);
       
     if (nd.hasSubDirs())
       node.add(new DefaultMutableTreeNode( 
         new Boolean(true) ));
   }
   return true;
 }
 public boolean hasSubDirs()
 {
   File[] files = listFiles();
   if (files == null)
     return false;
   for (int k=0; k<files.length; k++)
   {
     if (files[k].isDirectory())
       return true;
   }
   return false;
 }
 
 public int compareTo(FileNode toCompare)
 { 
   return  m_file.getName().rupareToIgnoreCase(
     toCompare.m_file.getName() ); 
 }
 protected File[] listFiles()
 {
   if (!m_file.isDirectory())
     return null;
   try
   {
     return m_file.listFiles();
   }
   catch (Exception ex)
   {
     JOptionPane.showMessageDialog(null, 
       "Error reading directory "+m_file.getAbsolutePath(),
       "Warning", JOptionPane.WARNING_MESSAGE);
     return null;
   }
 }

}



 </source>
   
  
 
  



File Tree with Tooltips

   <source lang="java">
 

/* Swing, Second Edition by Matthew Robinson, Pavel Vorobiev

  • /

import java.awt.*; import java.awt.event.*; import java.io.*; import java.util.*; import java.text.SimpleDateFormat; import javax.swing.*; import javax.swing.tree.*; import javax.swing.event.*; public class FileTree3

 extends JFrame 

{

 public static final ImageIcon ICON_COMPUTER = 
   new ImageIcon("computer.gif");
 public static final ImageIcon ICON_DISK = 
   new ImageIcon("disk.gif");
 public static final ImageIcon ICON_FOLDER = 
   new ImageIcon("folder.gif");
 public static final ImageIcon ICON_EXPANDEDFOLDER = 
   new ImageIcon("expandedfolder.gif");
 protected JTree  m_tree;
 protected DefaultTreeModel m_model;
 protected JTextField m_display;
 protected JPopupMenu m_popup;
 protected Action m_action;
 protected TreePath m_clickedPath;
 public FileTree3()
 {
   super("Directories Tree [Tool Tips]");
   setSize(400, 300);
   DefaultMutableTreeNode top = new DefaultMutableTreeNode(
     new IconData(ICON_COMPUTER, null, "Computer"));
   DefaultMutableTreeNode node;
   File[] roots = File.listRoots();
   for (int k=0; k<roots.length; k++)
   {
     node = new DefaultMutableTreeNode(new IconData(ICON_DISK, 
       null, new FileNode(roots[k])));
     top.add(node);
     node.add(new DefaultMutableTreeNode( new Boolean(true) ));
   }
   m_model = new DefaultTreeModel(top);

// NEW

   m_tree = new JTree(m_model)
   {
     public String getToolTipText(MouseEvent ev) 
     {
       if(ev == null)
         return null;
       TreePath path = m_tree.getPathForLocation(ev.getX(), 
         ev.getY());
       if (path != null)
       {
         FileNode fnode = getFileNode(getTreeNode(path));
         if (fnode==null)
           return null;
         File f = fnode.getFile();
         return (f==null ? null : f.getPath());
       }
       return null;
     }
   };
   ToolTipManager.sharedInstance().registerComponent(m_tree);
               m_tree.putClientProperty("JTree.lineStyle", "Angled");
   TreeCellRenderer renderer = new 
     IconCellRenderer();
   m_tree.setCellRenderer(renderer);
   m_tree.addTreeExpansionListener(new 
     DirExpansionListener());
   m_tree.addTreeSelectionListener(new 
     DirSelectionListener());
   m_tree.getSelectionModel().setSelectionMode(
     TreeSelectionModel.SINGLE_TREE_SELECTION); 
   m_tree.setShowsRootHandles(true); 
   m_tree.setEditable(false);
   JScrollPane s = new JScrollPane();
   s.getViewport().add(m_tree);
   getContentPane().add(s, BorderLayout.CENTER);
   m_display = new JTextField();
   m_display.setEditable(false);
   getContentPane().add(m_display, BorderLayout.NORTH);
   m_popup = new JPopupMenu();
   m_action = new AbstractAction() 
   { 
     public void actionPerformed(ActionEvent e)
     {
       if (m_clickedPath==null)
         return;
       if (m_tree.isExpanded(m_clickedPath))
         m_tree.collapsePath(m_clickedPath);
       else
         m_tree.expandPath(m_clickedPath);
     }
   };
   m_popup.add(m_action);
   m_popup.addSeparator();
   Action a1 = new AbstractAction("Delete") 
   { 
     public void actionPerformed(ActionEvent e)
     {
                               m_tree.repaint();
       JOptionPane.showMessageDialog(FileTree3.this, 
         "Delete option is not implemented",
         "Info", JOptionPane.INFORMATION_MESSAGE);
     }
   };
   m_popup.add(a1);
   Action a2 = new AbstractAction("Rename") 
   { 
     public void actionPerformed(ActionEvent e)
     {
                               m_tree.repaint();
       JOptionPane.showMessageDialog(FileTree3.this, 
         "Rename option is not implemented",
         "Info", JOptionPane.INFORMATION_MESSAGE);
     }
   };
   m_popup.add(a2);
   m_tree.add(m_popup);
   m_tree.addMouseListener(new PopupTrigger());
   WindowListener wndCloser = new WindowAdapter()
   {
     public void windowClosing(WindowEvent e) 
     {
       System.exit(0);
     }
   };
   addWindowListener(wndCloser);
   
   setVisible(true);
 }
 DefaultMutableTreeNode getTreeNode(TreePath path)
 {
   return (DefaultMutableTreeNode)(path.getLastPathComponent());
 }
 FileNode getFileNode(DefaultMutableTreeNode node)
 {
   if (node == null)
     return null;
   Object obj = node.getUserObject();
   if (obj instanceof IconData)
     obj = ((IconData)obj).getObject();
   if (obj instanceof FileNode)
     return (FileNode)obj;
   else
     return null;
 }
 class PopupTrigger extends MouseAdapter
 {
   public void mouseReleased(MouseEvent e)
   {
     if (e.isPopupTrigger())
     {
       int x = e.getX();
       int y = e.getY();
       TreePath path = m_tree.getPathForLocation(x, y);
       if (path != null)
       {
         if (m_tree.isExpanded(path))
           m_action.putValue(Action.NAME, "Collapse");
         else
           m_action.putValue(Action.NAME, "Expand");
         m_popup.show(m_tree, x, y);
         m_clickedPath = path;
       }
     }
   }
 }
   // Make sure expansion is threaded and updating the tree model
   // only occurs within the event dispatching thread.
   class DirExpansionListener implements TreeExpansionListener
   {
       public void treeExpanded(TreeExpansionEvent event)
       {
           final DefaultMutableTreeNode node = getTreeNode(
               event.getPath());
           final FileNode fnode = getFileNode(node);
           Thread runner = new Thread() 
           {
             public void run() 
             {
               if (fnode != null && fnode.expand(node)) 
               {
                 Runnable runnable = new Runnable() 
                 {
                   public void run() 
                   {
                      m_model.reload(node);
                   }
                 };
                 SwingUtilities.invokeLater(runnable);
               }
             }
           };
           runner.start();
       }
       public void treeCollapsed(TreeExpansionEvent event) {}
   }
 class DirSelectionListener 
   implements TreeSelectionListener 
 {
   public void valueChanged(TreeSelectionEvent event)
   {
     DefaultMutableTreeNode node = getTreeNode(
       event.getPath());
     FileNode fnode = getFileNode(node);
     if (fnode != null)
       m_display.setText(fnode.getFile().
         getAbsolutePath());
     else
       m_display.setText("");
   }
 }
 public static void main(String argv[]) 
 {
   new FileTree3();
 }

} class IconCellRenderer

 extends    JLabel 
 implements TreeCellRenderer

{

 protected Color m_textSelectionColor;
 protected Color m_textNonSelectionColor;
 protected Color m_bkSelectionColor;
 protected Color m_bkNonSelectionColor;
 protected Color m_borderSelectionColor;
 protected boolean m_selected;
 public IconCellRenderer()
 {
   super();
   m_textSelectionColor = UIManager.getColor(
     "Tree.selectionForeground");
   m_textNonSelectionColor = UIManager.getColor(
     "Tree.textForeground");
   m_bkSelectionColor = UIManager.getColor(
     "Tree.selectionBackground");
   m_bkNonSelectionColor = UIManager.getColor(
     "Tree.textBackground");
   m_borderSelectionColor = UIManager.getColor(
     "Tree.selectionBorderColor");
   setOpaque(false);
 }
 public Component getTreeCellRendererComponent(JTree tree, 
   Object value, boolean sel, boolean expanded, boolean leaf, 
   int row, boolean hasFocus) 
   
 {
   DefaultMutableTreeNode node = 
     (DefaultMutableTreeNode)value;
   Object obj = node.getUserObject();
   setText(obj.toString());
               if (obj instanceof Boolean)
                 setText("Retrieving data...");
   if (obj instanceof IconData)
   {
     IconData idata = (IconData)obj;
     if (expanded)
       setIcon(idata.getExpandedIcon());
     else
       setIcon(idata.getIcon());
   }
   else
     setIcon(null);
   setFont(tree.getFont());
   setForeground(sel ? m_textSelectionColor : 
     m_textNonSelectionColor);
   setBackground(sel ? m_bkSelectionColor : 
     m_bkNonSelectionColor);
   m_selected = sel;
   return this;
 }
   
 public void paintComponent(Graphics g) 
 {
   Color bColor = getBackground();
   Icon icon = getIcon();
   g.setColor(bColor);
   int offset = 0;
   if(icon != null && getText() != null) 
     offset = (icon.getIconWidth() + getIconTextGap());
   g.fillRect(offset, 0, getWidth() - 1 - offset,
     getHeight() - 1);
   
   if (m_selected) 
   {
     g.setColor(m_borderSelectionColor);
     g.drawRect(offset, 0, getWidth()-1-offset, getHeight()-1);
   }
   super.paintComponent(g);
   }

} class IconData {

 protected Icon   m_icon;
 protected Icon   m_expandedIcon;
 protected Object m_data;
 public IconData(Icon icon, Object data)
 {
   m_icon = icon;
   m_expandedIcon = null;
   m_data = data;
 }
 public IconData(Icon icon, Icon expandedIcon, Object data)
 {
   m_icon = icon;
   m_expandedIcon = expandedIcon;
   m_data = data;
 }
 public Icon getIcon() 
 { 
   return m_icon;
 }
 public Icon getExpandedIcon() 
 { 
   return m_expandedIcon!=null ? m_expandedIcon : m_icon;
 }
 public Object getObject() 
 { 
   return m_data;
 }
 public String toString() 
 { 
   return m_data.toString();
 }

} class FileNode {

 protected File m_file;
 public FileNode(File file)
 {
   m_file = file;
 }
 public File getFile() 
 { 
   return m_file;
 }
 public String toString() 
 { 
   return m_file.getName().length() > 0 ? m_file.getName() : 
     m_file.getPath();
 }
 public boolean expand(DefaultMutableTreeNode parent)
 {
   DefaultMutableTreeNode flag = 
     (DefaultMutableTreeNode)parent.getFirstChild();
   if (flag==null)    // No flag
     return false;
   Object obj = flag.getUserObject();
   if (!(obj instanceof Boolean))
     return false;      // Already expanded
   parent.removeAllChildren();  // Remove Flag
   File[] files = listFiles();
   if (files == null)
     return true;
   Vector v = new Vector();
   for (int k=0; k<files.length; k++)
   {
     File f = files[k];
     if (!(f.isDirectory()))
       continue;
     FileNode newNode = new FileNode(f);
     
     boolean isAdded = false;
     for (int i=0; i<v.size(); i++)
     {
       FileNode nd = (FileNode)v.elementAt(i);
       if (newNode.rupareTo(nd) < 0)
       {
         v.insertElementAt(newNode, i);
         isAdded = true;
         break;
       }
     }
     if (!isAdded)
       v.addElement(newNode);
   }
   for (int i=0; i<v.size(); i++)
   {
     FileNode nd = (FileNode)v.elementAt(i);
     IconData idata = new IconData(FileTree3.ICON_FOLDER, 
       FileTree3.ICON_EXPANDEDFOLDER, nd);
     DefaultMutableTreeNode node = new 
       DefaultMutableTreeNode(idata);
     parent.add(node);
       
     if (nd.hasSubDirs())
       node.add(new DefaultMutableTreeNode( 
         new Boolean(true) ));
   }
   return true;
 }
 public boolean hasSubDirs()
 {
   File[] files = listFiles();
   if (files == null)
     return false;
   for (int k=0; k<files.length; k++)
   {
     if (files[k].isDirectory())
       return true;
   }
   return false;
 }
 
 public int compareTo(FileNode toCompare)
 { 
   return  m_file.getName().rupareToIgnoreCase(
     toCompare.m_file.getName() ); 
 }
 protected File[] listFiles()
 {
   if (!m_file.isDirectory())
     return null;
   try
   {
     return m_file.listFiles();
   }
   catch (Exception ex)
   {
     JOptionPane.showMessageDialog(null, 
       "Error reading directory "+m_file.getAbsolutePath(),
       "Warning", JOptionPane.WARNING_MESSAGE);
     return null;
   }
 }

}



 </source>
   
  
 
  



Finding a Node in a JTree Component

   <source lang="java">
 

import javax.swing.JTree; import javax.swing.text.Position; import javax.swing.tree.TreePath; public class Main {

 public static void main(String[] argv) throws Exception {
   JTree tree = new JTree();
   // Search forward from first visible row looking for any visible node
   // whose name starts with prefix.
   int startRow = 0;
   String prefix = "b";
   TreePath path = tree.getNextMatch(prefix, startRow, Position.Bias.Forward);
   System.out.println(path);
 }

}


 </source>
   
  
 
  



Find the path regardless of visibility that matches the specified sequence of names

   <source lang="java">
 

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

 public static void main(String[] argv) throws Exception {
   JTree tree = new JTree();
   TreePath path = findByName(tree, new String[] { "JTree", "A", "a" });
 }
 public static TreePath findByName(JTree tree, String[] names) {
   TreeNode root = (TreeNode) tree.getModel().getRoot();
   return find(tree, new TreePath(root), names, 0);
 }
 private static TreePath find(JTree tree, TreePath parent, Object[] nodes, int depth) {
   TreeNode node = (TreeNode) parent.getLastPathComponent();
   Object o = node;
   if (o.equals(nodes[depth])) {
     if (depth == nodes.length - 1) {
       return parent;
     }
     if (node.getChildCount() >= 0) {
       for (Enumeration e = node.children(); e.hasMoreElements();) {
         TreeNode n = (TreeNode) e.nextElement();
         TreePath path = parent.pathByAddingChild(n);
         TreePath result = find(tree, path, nodes, depth + 1);
         if (result != null) {
           return result;
         }
       }
     }
   }
   return null;
 }

}


 </source>
   
  
 
  



Flush the internal cache of Row height

   <source lang="java">
 

import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; public class TreeRowHeightCache {

 public static void main(String[] argv) {
   JTree tree = new JTree();
   if (tree.getRowHeight() <= 0) {
     tree.setRowHeight(1);
   }
   tree.setRowHeight(0);
   JFrame frame = new JFrame("Image");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.add(new JScrollPane(tree));
   frame.setSize(380, 320);
   frame.setLocationRelativeTo(null);
   frame.setVisible(true);
 }

}


 </source>
   
  
 
  



Genealogy Tree

   <source lang="java">
 

/* From http://java.sun.ru/docs/books/tutorial/index.html */ /*

* Copyright (c) 2006 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:
*
* -Redistribution of source code must retain the above copyright notice, this
*  list of conditions and the following disclaimer.
*
* -Redistribution 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, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed, licensed or intended
* for use in the design, construction, operation or maintenance of any
* nuclear facility.
*/

/*

* A 1.4 example that uses the following files: GenealogyModel.java Person.java
* 
* Based on an example provided by tutorial reader Olivier Berlanger.
*/

import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Vector; import javax.swing.ButtonGroup; import javax.swing.Icon; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; public class GenealogyExample extends JPanel implements ActionListener {

 GenealogyTree tree;
 private static String SHOW_ANCESTOR_CMD = "showAncestor";
 public GenealogyExample() {
   super(new BorderLayout());
   //Construct the panel with the toggle buttons.
   JRadioButton showDescendant = new JRadioButton("Show descendants", true);
   final JRadioButton showAncestor = new JRadioButton("Show ancestors");
   ButtonGroup bGroup = new ButtonGroup();
   bGroup.add(showDescendant);
   bGroup.add(showAncestor);
   showDescendant.addActionListener(this);
   showAncestor.addActionListener(this);
   showAncestor.setActionCommand(SHOW_ANCESTOR_CMD);
   JPanel buttonPanel = new JPanel();
   buttonPanel.add(showDescendant);
   buttonPanel.add(showAncestor);
   //Construct the tree.
   tree = new GenealogyTree(getGenealogyGraph());
   JScrollPane scrollPane = new JScrollPane(tree);
   scrollPane.setPreferredSize(new Dimension(200, 200));
   //Add everything to this panel.
   add(buttonPanel, BorderLayout.PAGE_START);
   add(scrollPane, BorderLayout.CENTER);
 }
 /**
  * Required by the ActionListener interface. Handle events on the
  * showDescendant and showAncestore buttons.
  */
 public void actionPerformed(ActionEvent ae) {
   if (ae.getActionCommand() == SHOW_ANCESTOR_CMD) {
     tree.showAncestor(true);
   } else {
     tree.showAncestor(false);
   }
 }
 /**
  * Constructs the genealogy graph used by the model.
  */
 public Person getGenealogyGraph() {
   //the greatgrandparent generation
   Person a1 = new Person("Jack (great-granddaddy)");
   Person a2 = new Person("Jean (great-granny)");
   Person a3 = new Person("Albert (great-granddaddy)");
   Person a4 = new Person("Rae (great-granny)");
   Person a5 = new Person("Paul (great-granddaddy)");
   Person a6 = new Person("Josie (great-granny)");
   //the grandparent generation
   Person b1 = new Person("Peter (grandpa)");
   Person b2 = new Person("Zoe (grandma)");
   Person b3 = new Person("Simon (grandpa)");
   Person b4 = new Person("James (grandpa)");
   Person b5 = new Person("Bertha (grandma)");
   Person b6 = new Person("Veronica (grandma)");
   Person b7 = new Person("Anne (grandma)");
   Person b8 = new Person("Renee (grandma)");
   Person b9 = new Person("Joseph (grandpa)");
   //the parent generation
   Person c1 = new Person("Isabelle (mom)");
   Person c2 = new Person("Frank (dad)");
   Person c3 = new Person("Louis (dad)");
   Person c4 = new Person("Laurence (dad)");
   Person c5 = new Person("Valerie (mom)");
   Person c6 = new Person("Marie (mom)");
   Person c7 = new Person("Helen (mom)");
   Person c8 = new Person("Mark (dad)");
   Person c9 = new Person("Oliver (dad)");
   //the youngest generation
   Person d1 = new Person("Clement (boy)");
   Person d2 = new Person("Colin (boy)");
   Person.linkFamily(a1, a2, new Person[] { b1, b2, b3, b4 });
   Person.linkFamily(a3, a4, new Person[] { b5, b6, b7 });
   Person.linkFamily(a5, a6, new Person[] { b8, b9 });
   Person.linkFamily(b3, b6, new Person[] { c1, c2, c3 });
   Person.linkFamily(b4, b5, new Person[] { c4, c5, c6 });
   Person.linkFamily(b8, b7, new Person[] { c7, c8, c9 });
   Person.linkFamily(c4, c7, new Person[] { d1, d2 });
   return a1;
 }
 /**
  * Create the GUI and show it. For thread safety, this method should be
  * invoked from the event-dispatching thread.
  */
 private static void createAndShowGUI() {
   //Make sure we have nice window decorations.
   JFrame.setDefaultLookAndFeelDecorated(true);
   //Create and set up the window.
   JFrame frame = new JFrame("GenealogyExample");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   //Create and set up the content pane.
   GenealogyExample newContentPane = new GenealogyExample();
   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();
     }
   });
 }

} class GenealogyModel implements TreeModel {

 private boolean showAncestors;
 private Vector treeModelListeners = new Vector();
 private Person rootPerson;
 public GenealogyModel(Person root) {
   showAncestors = false;
   rootPerson = root;
 }
 /**
  * Used to toggle between show ancestors/show descendant and to change the
  * root of the tree.
  */
 public void showAncestor(boolean b, Object newRoot) {
   showAncestors = b;
   Person oldRoot = rootPerson;
   if (newRoot != null) {
     rootPerson = (Person) newRoot;
   }
   fireTreeStructureChanged(oldRoot);
 }
 //////////////// Fire events //////////////////////////////////////////////
 /**
  * The only event raised by this model is TreeStructureChanged with the root
  * as path, i.e. the whole tree has changed.
  */
 protected void fireTreeStructureChanged(Person oldRoot) {
   int len = treeModelListeners.size();
   TreeModelEvent e = new TreeModelEvent(this, new Object[] { oldRoot });
   for (int i = 0; i < len; i++) {
     ((TreeModelListener) treeModelListeners.elementAt(i))
         .treeStructureChanged(e);
   }
 }
 //////////////// TreeModel interface implementation ///////////////////////
 /**
  * Adds a listener for the TreeModelEvent posted after the tree changes.
  */
 public void addTreeModelListener(TreeModelListener l) {
   treeModelListeners.addElement(l);
 }
 /**
  * Returns the child of parent at index index in the parent"s child array.
  */
 public Object getChild(Object parent, int index) {
   Person p = (Person) parent;
   if (showAncestors) {
     if ((index > 0) && (p.getFather() != null)) {
       return p.getMother();
     }
     return p.getFather();
   }
   return p.getChildAt(index);
 }
 /**
  * Returns the number of children of parent.
  */
 public int getChildCount(Object parent) {
   Person p = (Person) parent;
   if (showAncestors) {
     int count = 0;
     if (p.getFather() != null) {
       count++;
     }
     if (p.getMother() != null) {
       count++;
     }
     return count;
   }
   return p.getChildCount();
 }
 /**
  * Returns the index of child in parent.
  */
 public int getIndexOfChild(Object parent, Object child) {
   Person p = (Person) parent;
   if (showAncestors) {
     int count = 0;
     Person father = p.getFather();
     if (father != null) {
       count++;
       if (father == child) {
         return 0;
       }
     }
     if (p.getMother() != child) {
       return count;
     }
     return -1;
   }
   return p.getIndexOfChild((Person) child);
 }
 /**
  * Returns the root of the tree.
  */
 public Object getRoot() {
   return rootPerson;
 }
 /**
  * Returns true if node is a leaf.
  */
 public boolean isLeaf(Object node) {
   Person p = (Person) node;
   if (showAncestors) {
     return ((p.getFather() == null) && (p.getMother() == null));
   }
   return p.getChildCount() == 0;
 }
 /**
  * Removes a listener previously added with addTreeModelListener().
  */
 public void removeTreeModelListener(TreeModelListener l) {
   treeModelListeners.removeElement(l);
 }
 /**
  * Messaged when the user has altered the value for the item identified by
  * path to newValue. Not used by this model.
  */
 public void valueForPathChanged(TreePath path, Object newValue) {
   System.out.println("*** valueForPathChanged : " + path + " --> "
       + newValue);
 }

} class Person {

 Person father;
 Person mother;
 Vector children;
 private String name;
 public Person(String name) {
   this.name = name;
   mother = father = null;
   children = new Vector();
 }
 /**
  * Link together all members of a family.
  * 
  * @param pa
  *            the father
  * @param ma
  *            the mother
  * @param kids
  *            the children
  */
 public static void linkFamily(Person pa, Person ma, Person[] kids) {
   int len = kids.length;
   Person kid = null;
   for (int i = 0; i < len; i++) {
     kid = kids[i];
     pa.children.addElement(kid);
     ma.children.addElement(kid);
     kid.father = pa;
     kid.mother = ma;
   }
 }
 /// getter methods ///////////////////////////////////
 public String toString() {
   return name;
 }
 public String getName() {
   return name;
 }
 public Person getFather() {
   return father;
 }
 public Person getMother() {
   return mother;
 }
 public int getChildCount() {
   return children.size();
 }
 public Person getChildAt(int i) {
   return (Person) children.elementAt(i);
 }
 public int getIndexOfChild(Person kid) {
   return children.indexOf(kid);
 }

} class GenealogyTree extends JTree {

 GenealogyModel model;
 public GenealogyTree(Person graphNode) {
   super(new GenealogyModel(graphNode));
   getSelectionModel().setSelectionMode(
       TreeSelectionModel.SINGLE_TREE_SELECTION);
   DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
   Icon personIcon = null;
   renderer.setLeafIcon(personIcon);
   renderer.setClosedIcon(personIcon);
   renderer.setOpenIcon(personIcon);
   setCellRenderer(renderer);
 }
 /**
  * Get the selected item in the tree, and call showAncestor with this item
  * on the model.
  */
 public void showAncestor(boolean b) {
   Object newRoot = null;
   TreePath path = getSelectionModel().getSelectionPath();
   if (path != null) {
     newRoot = path.getLastPathComponent();
   }
   ((GenealogyModel) getModel()).showAncestor(b, newRoot);
 }

}


 </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>
   
  
 
  



Getting the Selected Nodes in a JTree Component

   <source lang="java">
 

import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.tree.TreePath; public class Main {

 public static void main(String[] argv) throws Exception {
   JTree tree = new JTree();
   JFrame f = new JFrame();
   f.add(new JScrollPane(tree));
   f.setSize(300, 300);
   f.setVisible(true);
   // Get paths of all selected nodes
   TreePath[] paths = tree.getSelectionPaths();
 }

}


 </source>
   
  
 
  



Get tree path from TreeNode

   <source lang="java">

import java.util.ArrayList; import java.util.List; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; public class Utils {

 public static TreePath getPath(TreeNode treeNode) {
   List<Object> nodes = new ArrayList<Object>();
   if (treeNode != null) {
     nodes.add(treeNode);
     treeNode = treeNode.getParent();
     while (treeNode != null) {
       nodes.add(0, treeNode);
       treeNode = treeNode.getParent();
     }
   }
   return nodes.isEmpty() ? null : new TreePath(nodes.toArray());
 }

}

 </source>
   
  
 
  



Have a popup attached to a JTree

   <source lang="java">
 

import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; public class Main extends JPanel {

 DefaultMutableTreeNode root = new DefaultMutableTreeNode("root", true),
     node1 = new DefaultMutableTreeNode("node 1", true), node2 = new DefaultMutableTreeNode(
         "node 2", true), node3 = new DefaultMutableTreeNode("node 3", true);
 MyJTree tree = new MyJTree(root);
 public Main() {
   root.add(node1);
   node1.add(node2);
   root.add(node3);
   setLayout(new BorderLayout());
   add(new JScrollPane((JTree) tree), "Center");
 }
 public static void main(String s[]) {
   JFrame frame = new JFrame("Tree With Popup");
   Main panel = new Main();
   frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
   frame.setBackground(Color.lightGray);
   frame.getContentPane().add(panel, "Center");
   frame.setSize(panel.getPreferredSize());
   frame.setVisible(true);
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 }

} class MyJTree extends JTree implements ActionListener {

 JPopupMenu popup = new JPopupMenu();
 JMenuItem mi = new JMenuItem("Insert a children");
 MyJTree(DefaultMutableTreeNode dmtn) {
   super(dmtn);    
   mi.addActionListener(this);
   mi.setActionCommand("insert");
   popup.add(mi);
   mi = new JMenuItem("Remove this node");
   mi.addActionListener(this);
   mi.setActionCommand("remove");
   popup.add(mi);
   addMouseListener(new MouseAdapter() {
     public void mouseReleased(MouseEvent e) {
       if (e.isPopupTrigger()) {
         popup.show((JComponent) e.getSource(), e.getX(), e.getY());
       }
     }
   });
 }
 public void actionPerformed(ActionEvent ae) {
   DefaultMutableTreeNode dmtn, node;
   TreePath path = this.getSelectionPath();
   dmtn = (DefaultMutableTreeNode) path.getLastPathComponent();
   if (ae.getActionCommand().equals("insert")) {
     node = new DefaultMutableTreeNode("children");
     dmtn.add(node);
     ((DefaultTreeModel) this.getModel()).nodeStructureChanged((TreeNode) dmtn);
   }
   if (ae.getActionCommand().equals("remove")) {
     node = (DefaultMutableTreeNode) dmtn.getParent();
     int nodeIndex = node.getIndex(dmtn);
     dmtn.removeAllChildren();
     node.remove(nodeIndex);
     ((DefaultTreeModel) this.getModel()).nodeStructureChanged((TreeNode) dmtn);
   }
 }

}


 </source>
   
  
 
  



Have the row height for each row computed individually

   <source lang="java">
 

import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; public class TreeRowHeightCalculation {

 public static void main(String[] argv) {
   JTree tree = new JTree();
   tree.setRowHeight(0);
   JFrame frame = new JFrame("tree row height calculation");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.add(new JScrollPane(tree));
   frame.setSize(380, 320);
   frame.setLocationRelativeTo(null);
   frame.setVisible(true);
 }

}


 </source>
   
  
 
  



implements TreeSelectionListener to create your own listener

   <source lang="java">
 

/* Swing, Second Edition by Matthew Robinson, Pavel Vorobiev

  • /

import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; import javax.swing.tree.*; import javax.swing.event.*; public class Tree1

 extends JFrame 

{

 protected JTree  m_tree = null;
 protected DefaultTreeModel m_model = null;
 protected JTextField m_display;
 public Tree1()
 {
   super("Sample Tree [OID]");
   setSize(400, 300);
       Object[] nodes = new Object[5];
   DefaultMutableTreeNode top = new DefaultMutableTreeNode(
     new OidNode(1, "ISO"));
   DefaultMutableTreeNode parent = top;
   nodes[0] = top;
   DefaultMutableTreeNode node = new DefaultMutableTreeNode(
     new OidNode(0, "standard"));
   parent.add(node);
   node = new DefaultMutableTreeNode(new OidNode(2, 
     "member-body"));
   parent.add(node);
   node = new DefaultMutableTreeNode(new OidNode(3, "org"));
   parent.add(node);
   parent = node;
   nodes[1] = parent;
   node = new DefaultMutableTreeNode(new OidNode(6, "dod"));
   parent.add(node);
   parent = node;
   nodes[2] = parent;
   node = new DefaultMutableTreeNode(new OidNode(1, 
     "internet"));
   parent.add(node);
   parent = node;
   nodes[3] = parent;
   node = new DefaultMutableTreeNode(new OidNode(1, 
     "directory"));
   parent.add(node);
   node = new DefaultMutableTreeNode(new OidNode(2, 
     "mgmt"));
   parent.add(node);
   nodes[4] = node;
   node.add(new DefaultMutableTreeNode(new OidNode(1, 
     "mib-2")));
   node = new DefaultMutableTreeNode(new OidNode(3, 
     "experimental"));
   parent.add(node);
   node = new DefaultMutableTreeNode(new OidNode(4, 
     "private"));
   node.add(new DefaultMutableTreeNode(new OidNode(1, 
     "enterprises")));
   parent.add(node);
   node = new DefaultMutableTreeNode(new OidNode(5, 
     "security"));
   parent.add(node);
   node = new DefaultMutableTreeNode(new OidNode(6, 
     "snmpV2"));
   parent.add(node);
   node = new DefaultMutableTreeNode(new OidNode(7, 
     "mail"));
   parent.add(node);
   m_model = new DefaultTreeModel(top);
   m_tree = new JTree(m_model);
   DefaultTreeCellRenderer renderer = new 
     DefaultTreeCellRenderer();
   renderer.setOpenIcon(new ImageIcon("opened.gif"));
   renderer.setClosedIcon(new ImageIcon("closed.gif"));
   renderer.setLeafIcon(new ImageIcon("leaf.gif"));
   m_tree.setCellRenderer(renderer);
   m_tree.setShowsRootHandles(true); 
   m_tree.setEditable(false);
   TreePath path = new TreePath(nodes);
   m_tree.setSelectionPath(path);
   m_tree.addTreeSelectionListener(new 
     OidSelectionListener());
   JScrollPane s = new JScrollPane();
   s.getViewport().add(m_tree);
   getContentPane().add(s, BorderLayout.CENTER);
   m_display = new JTextField();
   m_display.setEditable(false);
   getContentPane().add(m_display, BorderLayout.SOUTH);
   WindowListener wndCloser = new WindowAdapter()
   {
     public void windowClosing(WindowEvent e) 
     {
       System.exit(0);
     }
   };
   addWindowListener(wndCloser);
   
   setVisible(true);
 }
 public static void main(String argv[]) 
 {
   new Tree1();
 }
 class OidSelectionListener 
   implements TreeSelectionListener 
 {
   public void valueChanged(TreeSelectionEvent e)
   {
     TreePath path = e.getPath();
     Object[] nodes = path.getPath();
     String oid = "";
     for (int k=0; k<nodes.length; k++)
     {
       DefaultMutableTreeNode node = 
         (DefaultMutableTreeNode)nodes[k];
       OidNode nd = (OidNode)node.getUserObject();
       oid += "."+nd.getId();
     }
     m_display.setText(oid);
   }
 }

} class OidNode {

 protected int    m_id;
 protected String m_name;
 public OidNode(int id, String name)
 {
   m_id = id;
   m_name = name;
 }
 public int getId() 
 { 
   return m_id;
 }
 public String getName() 
 { 
   return m_name;
 }
 public String toString() 
 { 
   return m_name;
 }

}



 </source>
   
  
 
  



Installs custom icons

   <source lang="java">
 

/* Java Swing, 2nd Edition By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole ISBN: 0-596-00408-7 Publisher: O"Reilly

  • /

// TestTree3.java //A variation on TestTree that installs custom icons. The icons installed //will appear on *every* tree. // import java.awt.BorderLayout; import java.util.Hashtable; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JTree; import javax.swing.UIManager; import javax.swing.tree.DefaultTreeModel; public class TestTree3 extends JFrame {

 JTree tree;
 DefaultTreeModel treeModel;
 public TestTree3() {
   super("Tree Test Example");
   setSize(200, 150);
   setDefaultCloseOperation(EXIT_ON_CLOSE);
   // Add our own customized tree icons.
   UIManager.put("Tree.leafIcon", new ImageIcon("world.gif"));
   UIManager.put("Tree.openIcon", new ImageIcon("door.open.gif"));
   UIManager.put("Tree.closedIcon", new ImageIcon("door.closed.gif"));
   UIManager.put("Tree.expandedIcon", new ImageIcon("unlocked.gif"));
   UIManager.put("Tree.collapsedIcon", new ImageIcon("locked.gif"));
 }
 public void init() {
   // Build the hierarchy of containers & objects.
   String[] schoolyard = { "School", "Playground", "Parking Lot", "Field" };
   String[] mainstreet = { "Grocery", "Shoe Shop", "Five & Dime",
       "Post Office" };
   String[] highway = { "Gas Station", "Convenience Store" };
   String[] housing = { "Victorian_blue", "Faux Colonial",
       "Victorian_white" };
   String[] housing2 = { "Mission", "Ranch", "Condo" };
   Hashtable homeHash = new Hashtable();
   homeHash.put("Residential 1", housing);
   homeHash.put("Residential 2", housing2);
   Hashtable cityHash = new Hashtable();
   cityHash.put("School grounds", schoolyard);
   cityHash.put("Downtown", mainstreet);
   cityHash.put("Highway", highway);
   cityHash.put("Housing", homeHash);
   Hashtable worldHash = new Hashtable();
   worldHash.put("My First VRML World", cityHash);
   // Build our tree out of our big hash table.
   tree = new JTree(worldHash);
   // Pick an angled line style.
   tree.putClientProperty("JTree.lineStyle", "Angled");
   getContentPane().add(tree, BorderLayout.CENTER);
 }
 public static void main(String args[]) {
   TestTree3 tt = new TestTree3();
   tt.init();
   tt.setVisible(true);
 }

}


 </source>
   
  
 
  



Install ToolTips for Tree (JTree)

   <source lang="java">
 

/* Definitive Guide to Swing for Java 2, Second Edition By John Zukowski ISBN: 1-893115-78-X Publisher: APress

  • /

import java.awt.BorderLayout; import java.awt.ruponent; import java.util.Dictionary; import java.util.Properties; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.ToolTipManager; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.TreeCellRenderer; public class TreeTips {

 public static void main(String args[]) {
   JFrame frame = new JFrame("Tree Tips");
   Properties props = System.getProperties();
   JTree tree = new JTree(props);
   ToolTipManager.sharedInstance().registerComponent(tree);
   TreeCellRenderer renderer = new ToolTipTreeCellRenderer(props);
   tree.setCellRenderer(renderer);
   JScrollPane scrollPane = new JScrollPane(tree);
   frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
   frame.setSize(300, 150);
   frame.setVisible(true);
 }

} class ToolTipTreeCellRenderer implements TreeCellRenderer {

 DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
 Dictionary tipTable;
 public ToolTipTreeCellRenderer(Dictionary tipTable) {
   this.tipTable = tipTable;
 }
 public Component getTreeCellRendererComponent(JTree tree, Object value,
     boolean selected, boolean expanded, boolean leaf, int row,
     boolean hasFocus) {
   renderer.getTreeCellRendererComponent(tree, value, selected, expanded,
       leaf, row, hasFocus);
   if (value != null) {
     Object tipKey;
     if (value instanceof DefaultMutableTreeNode) {
       tipKey = ((DefaultMutableTreeNode) value).getUserObject();
     } else {
       tipKey = tree.convertValueToText(value, selected, expanded,
           leaf, row, hasFocus);
     }
     Object tip = tipTable.get(tipKey);
     if (tip != null) {
       renderer.setToolTipText(tip.toString());
     } else {
       renderer.setToolTipText(null);
     }
   }
   return renderer;
 }

}


 </source>
   
  
 
  



JTree drag and drop utilites

   <source lang="java">
  

/* Copyright (c) 2006, 2009, Carl Burch. License information is located in the

* com.cburch.logisim.Main source code and at www.cburch.ru/logisim/. */

import java.awt.AlphaComposite; import java.awt.Graphics2D; import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.dnd.DnDConstants; import java.awt.dnd.DragGestureEvent; import java.awt.dnd.DragGestureListener; import java.awt.dnd.DragSource; import java.awt.dnd.DragSourceDragEvent; import java.awt.dnd.DragSourceDropEvent; import java.awt.dnd.DragSourceEvent; import java.awt.dnd.DragSourceListener; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetListener; import java.awt.image.BufferedImage; import java.util.Arrays; import javax.swing.JComponent; import javax.swing.JTree; import javax.swing.tree.TreePath; /* This comes from "Denis" at http://forum.java.sun.ru/thread.jspa?forumID=57&threadID=296255 */ /*

* My program use 4 classes. The application displays two trees.
* You can drag (move by default or copy with ctrl pressed) a node from the left tree to the right one, from the right to the left and inside the same tree.
* The rules for moving are :
*   - you can"t move the root
*   - you can"t move the selected node to its subtree (in the same tree).
*   - you can"t move the selected node to itself (in the same tree).
*   - you can"t move the selected node to its parent (in the same tree).
*   - you can move a node to anywhere you want according to the 4 previous rules.
*  The rules for copying are :
*   - you can copy a node to anywhere you want.
*
* In the implementation I used DnD version of Java 1.3 because in 1.4 the DnD is too restrictive :
* you can"t do what you want (displaying the image of the node while dragging, changing the cursor
* according to where you are dragging, etc...). In 1.4, the DnD is based on the 1.3 version but
* it is too encapsulated.
*/

public class JTreeUtil {

   private static final Insets DEFAULT_INSETS = new Insets(20, 20, 20, 20);
   private static final DataFlavor NODE_FLAVOR = new DataFlavor(
           DataFlavor.javaJVMLocalObjectMimeType, "Node");
   private static Object draggedNode;
   private static BufferedImage image = null; // buff image
   private static class TransferableNode implements Transferable {
       private Object node;
       private DataFlavor[] flavors = { NODE_FLAVOR };
       public TransferableNode(Object nd) {
           node = nd;
       }
       public synchronized Object getTransferData(DataFlavor flavor)
               throws UnsupportedFlavorException {
           if(flavor == NODE_FLAVOR) {
               return node;
           } else {
               throw new UnsupportedFlavorException(flavor);
           }
       }
       public DataFlavor[] getTransferDataFlavors() {
           return flavors;
       }
       public boolean isDataFlavorSupported(DataFlavor flavor) {
           return Arrays.asList(flavors).contains(flavor);
       }
   }
   /*
    * This class is the most important. It manages all the DnD behavior. It is
    * abstract because it contains two abstract methods:
    *   public abstract boolean canPerformAction(JTree target,
    *     Object draggedNode, int action, Point location);
    *   public abstract boolean executeDrop(DNDTree tree,
    *     Object draggedNode, Object newParentNode, int action);
    * we have to override to give the required behavior of DnD in your tree.
    */
   private static class TreeTransferHandler implements
           DragGestureListener, DragSourceListener, DropTargetListener {
       private JTree tree;
       private JTreeDragController controller;
       private DragSource dragSource; // dragsource
       private Rectangle rect2D = new Rectangle();
       private boolean drawImage;
       protected TreeTransferHandler(JTree tree, JTreeDragController controller,
               int action, boolean drawIcon) {
           this.tree = tree;
           this.controller = controller;
           drawImage = drawIcon;
           dragSource = new DragSource();
           dragSource.createDefaultDragGestureRecognizer(tree, action, this);
       }
       /* Methods for DragSourceListener */
       public void dragDropEnd(DragSourceDropEvent dsde) {
           /*
           if(dsde.getDropSuccess()
                   && dsde.getDropAction() == DnDConstants.ACTION_MOVE
                   && draggedNodeParent != null) {
               ((DefaultTreeModel) tree.getModel())
                       .nodeStructureChanged(draggedNodeParent);
           }
           */
       }
       public final void dragEnter(DragSourceDragEvent dsde) {
           int action = dsde.getDropAction();
           if(action == DnDConstants.ACTION_COPY) {
               dsde.getDragSourceContext().setCursor(
                       DragSource.DefaultCopyDrop);
           } else {
               if(action == DnDConstants.ACTION_MOVE) {
                   dsde.getDragSourceContext().setCursor(
                           DragSource.DefaultMoveDrop);
               } else {
                   dsde.getDragSourceContext().setCursor(
                           DragSource.DefaultMoveNoDrop);
               }
           }
       }
       public final void dragOver(DragSourceDragEvent dsde) {
           int action = dsde.getDropAction();
           if(action == DnDConstants.ACTION_COPY) {
               dsde.getDragSourceContext().setCursor(
                       DragSource.DefaultCopyDrop);
           } else {
               if(action == DnDConstants.ACTION_MOVE) {
                   dsde.getDragSourceContext().setCursor(
                           DragSource.DefaultMoveDrop);
               } else {
                   dsde.getDragSourceContext().setCursor(
                           DragSource.DefaultMoveNoDrop);
               }
           }
       }
       public final void dropActionChanged(DragSourceDragEvent dsde) {
           int action = dsde.getDropAction();
           if(action == DnDConstants.ACTION_COPY) {
               dsde.getDragSourceContext().setCursor(
                       DragSource.DefaultCopyDrop);
           } else {
               if(action == DnDConstants.ACTION_MOVE) {
                   dsde.getDragSourceContext().setCursor(
                           DragSource.DefaultMoveDrop);
               } else {
                   dsde.getDragSourceContext().setCursor(
                           DragSource.DefaultMoveNoDrop);
               }
           }
       }
       public final void dragExit(DragSourceEvent dse) {
           dse.getDragSourceContext().setCursor(DragSource.DefaultMoveNoDrop);
       }
       /* Methods for DragGestureListener */
       public final void dragGestureRecognized(DragGestureEvent dge) {
           TreePath path = tree.getSelectionPath();
           if(path != null) {
               draggedNode = path.getLastPathComponent();
               if(drawImage) {
                   Rectangle pathBounds = tree.getPathBounds(path); // getpathbounds
                                                                       // of
                                                                       // selectionpath
                   JComponent lbl = (JComponent) tree
                           .getCellRenderer()
                           .getTreeCellRendererComponent(
                                   tree,
                                   draggedNode,
                                   false,
                                   tree.isExpanded(path),
                                   tree.getModel() .isLeaf(path.getLastPathComponent()),
                                   0, false);// returning the label
                   lbl.setBounds(pathBounds);// setting bounds to lbl
                   image = new BufferedImage(lbl.getWidth(), lbl.getHeight(),
                           java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE);// buffered
                                                                           // image
                                                                           // reference
                                                                           // passing
                                                                           // the
                                                                           // label"s
                                                                           // ht
                                                                           // and
                                                                           // width
                   Graphics2D graphics = image.createGraphics();// creating
                                                                   // the
                                                                   // graphics
                                                                   // for
                                                                   // buffered
                                                                   // image
                   graphics.setComposite(AlphaComposite.getInstance(
                           AlphaComposite.SRC_OVER, 0.5f)); // Sets the
                                                               // Composite for
                                                               // the
                                                               // Graphics2D
                                                               // context
                   lbl.setOpaque(false);
                   lbl.paint(graphics); // painting the graphics to label
                   graphics.dispose();
               }
               dragSource.startDrag(dge, DragSource.DefaultMoveNoDrop, image,
                       new Point(0, 0), new TransferableNode(draggedNode),
                       this);
           }
       }
       /* Methods for DropTargetListener */
       public final void dragEnter(DropTargetDragEvent dtde) {
           Point pt = dtde.getLocation();
           int action = dtde.getDropAction();
           if(drawImage) {
               paintImage(pt);
           }
           if(controller.canPerformAction(tree, draggedNode, action, pt)) {
               dtde.acceptDrag(action);
           } else {
               dtde.rejectDrag();
           }
       }
       public final void dragExit(DropTargetEvent dte) {
           if(drawImage) {
               clearImage();
           }
       }
       public final void dragOver(DropTargetDragEvent dtde) {
           Point pt = dtde.getLocation();
           int action = dtde.getDropAction();
           autoscroll(tree, pt);
           if(drawImage) {
               paintImage(pt);
           }
           if(controller.canPerformAction(tree, draggedNode, action, pt)) {
               dtde.acceptDrag(action);
           } else {
               dtde.rejectDrag();
           }
       }
       public final void dropActionChanged(DropTargetDragEvent dtde) {
           Point pt = dtde.getLocation();
           int action = dtde.getDropAction();
           if(drawImage) {
               paintImage(pt);
           }
           if(controller.canPerformAction(tree, draggedNode, action, pt)) {
               dtde.acceptDrag(action);
           } else {
               dtde.rejectDrag();
           }
       }
       public final void drop(DropTargetDropEvent dtde) {
           try {
               if(drawImage) {
                   clearImage();
               }
               int action = dtde.getDropAction();
               Transferable transferable = dtde.getTransferable();
               Point pt = dtde.getLocation();
               if(transferable
                       .isDataFlavorSupported(NODE_FLAVOR)
                       && controller.canPerformAction(tree, draggedNode, action, pt)) {
                   TreePath pathTarget = tree.getPathForLocation(pt.x, pt.y);
                   Object node = transferable.getTransferData(NODE_FLAVOR);
                   Object newParentNode = pathTarget.getLastPathComponent();
                   if(controller.executeDrop(tree, node, newParentNode, action)) {
                       dtde.acceptDrop(action);
                       dtde.dropComplete(true);
                       return;
                   }
               }
               dtde.rejectDrop();
               dtde.dropComplete(false);
           } catch(Exception e) {
               dtde.rejectDrop();
               dtde.dropComplete(false);
           }
       }
       private final void paintImage(Point pt) {
           tree.paintImmediately(rect2D.getBounds());
           rect2D.setRect((int) pt.getX(), (int) pt.getY(), image.getWidth(),
                   image.getHeight());
           tree.getGraphics().drawImage(image, (int) pt.getX(),
                   (int) pt.getY(), tree);
       }
       private final void clearImage() {
           tree.paintImmediately(rect2D.getBounds());
       }
   }
   
   public static void configureDragAndDrop(JTree tree, JTreeDragController controller) {
       tree.setAutoscrolls(true);
       new TreeTransferHandler(tree, controller, DnDConstants.ACTION_COPY_OR_MOVE, true);
   }
   private static void autoscroll(JTree tree, Point cursorLocation) {
       Insets insets = DEFAULT_INSETS;
       Rectangle outer = tree.getVisibleRect();
       Rectangle inner = new Rectangle(outer.x + insets.left, outer.y
               + insets.top, outer.width - (insets.left + insets.right),
               outer.height - (insets.top + insets.bottom));
       if(!inner.contains(cursorLocation)) {
           Rectangle scrollRect = new Rectangle(cursorLocation.x
                   - insets.left, cursorLocation.y - insets.top,
                   insets.left + insets.right, insets.top + insets.bottom);
           tree.scrollRectToVisible(scrollRect);
       }
   }

} /* Copyright (c) 2006, 2009, Carl Burch. License information is located in the

* com.cburch.logisim.Main source code and at www.cburch.ru/logisim/. */

/* This comes from "Denis" at http://forum.java.sun.ru/thread.jspa?forumID=57&threadID=296255 */ /*

* My program use 4 classes. The application displays two trees.
* You can drag (move by default or copy with ctrl pressed) a node from the left tree to the right one, from the right to the left and inside the same tree.
* The rules for moving are :
*   - you can"t move the root
*   - you can"t move the selected node to its subtree (in the same tree).
*   - you can"t move the selected node to itself (in the same tree).
*   - you can"t move the selected node to its parent (in the same tree).
*   - you can move a node to anywhere you want according to the 4 previous rules.
*  The rules for copying are :
*   - you can copy a node to anywhere you want.
*
* In the implementation I used DnD version of Java 1.3 because in 1.4 the DnD is too restrictive :
* you can"t do what you want (displaying the image of the node while dragging, changing the cursor
* according to where you are dragging, etc...). In 1.4, the DnD is based on the 1.3 version but
* it is too encapsulated.
*/

interface JTreeDragController {

   public boolean canPerformAction(JTree target, Object draggedNode,
           int action, Point location);
   public boolean executeDrop(JTree tree, Object draggedNode,
           Object newParentNode, int action);

}


 </source>
   
  
 
  



JTree.DynamicUtilTreeNode.createChildren

   <source lang="java">
 

import java.awt.BorderLayout; import java.util.Hashtable; import java.util.Properties; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; public class TreeUtilSample {

 public static void main(String args[]) {
   JFrame frame = new JFrame("DynamicUtilTreeNode Hashtable");
   DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
   Hashtable hashtable = new Hashtable();
   hashtable.put("One", args);
   hashtable.put("Two", new String[] { "Mercury", "Venus", "Mars" });
   Hashtable innerHashtable = new Hashtable();
   Properties props = System.getProperties();
   innerHashtable.put(props, props);
   innerHashtable.put("Two", new String[] { "Mercury", "Venus", "Mars" });
   hashtable.put("Three", innerHashtable);
   JTree.DynamicUtilTreeNode.createChildren(root, hashtable);
   JTree tree = new JTree(root);
   JScrollPane scrollPane = new JScrollPane(tree);
   frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
   frame.setSize(300, 150);
   frame.setVisible(true);
 }

}


 </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>
   
  
 
  



Listening for Expansion and Collapse Events in a JTree Component

   <source lang="java">
 

import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.event.TreeExpansionEvent; import javax.swing.event.TreeExpansionListener; import javax.swing.event.TreeWillExpandListener; import javax.swing.tree.ExpandVetoException; import javax.swing.tree.TreePath; public class Main {

 public static void main() {
   JTree tree = new JTree();
   tree.addTreeWillExpandListener(new MyTreeWillExpandListener());
   tree.addTreeExpansionListener(new MyTreeExpansionListener());
   JFrame f = new JFrame();
   f.add(new JScrollPane(tree));
   f.setSize(300, 300);
   f.setVisible(true);
 }

} class MyTreeWillExpandListener implements TreeWillExpandListener {

 public void treeWillExpand(TreeExpansionEvent evt) throws ExpandVetoException {
   JTree tree = (JTree) evt.getSource();
   TreePath path = evt.getPath();
   boolean veto = false;
   if (veto) {
     throw new ExpandVetoException(evt);
   }
 }
 public void treeWillCollapse(TreeExpansionEvent evt) throws ExpandVetoException {
   JTree tree = (JTree) evt.getSource();
   TreePath path = evt.getPath();
   boolean veto = false;
   if (veto) {
     throw new ExpandVetoException(evt);
   }
 }

} class MyTreeExpansionListener implements TreeExpansionListener {

 public void treeExpanded(TreeExpansionEvent evt) {
   JTree tree = (JTree) evt.getSource();
   TreePath path = evt.getPath();
   System.out.println("treeExpanded");
 }
 public void treeCollapsed(TreeExpansionEvent evt) {
   JTree tree = (JTree) evt.getSource();
   TreePath path = evt.getPath();
   System.out.println("treeCollapsed");
 }

}


 </source>
   
  
 
  



Listening for Selection Events in a JTree Component

   <source lang="java">
 

import javax.swing.JTree; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.TreePath; public class Main {

 public static void main(String[] argv) throws Exception {
   JTree tree = new JTree();
   tree.addTreeSelectionListener(new TreeSelectionListener() {
     public void valueChanged(TreeSelectionEvent evt) {
       TreePath[] paths = evt.getPaths();
       for (int i = 0; i < paths.length; i++) {
         if (evt.isAddedPath(i)) {
           System.out.println("This node has been selected");
         } else {
           System.out.println("This node has been deselected"); 
         }
       }
     }
   });
 }

}


 </source>
   
  
 
  



Preventing Expansion or Collapse of a Node in a JTree: override JTree.setExpandedState()

   <source lang="java">
 

import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.tree.TreePath; public class Main {

 public static void main(String[] argv) {
   JTree tree = new JTree() {
     protected void setExpandedState(TreePath path, boolean state) {
       
       if (state) {
         super.setExpandedState(path, state);
       }
     }
   };
   JFrame frame = new JFrame("Ignore all collapse requests");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.add(new JScrollPane(tree));
   frame.setSize(380, 320);
   frame.setLocationRelativeTo(null);
   frame.setVisible(true);
 }

}


 </source>
   
  
 
  



Preventing the Expansion or Collapse of a Node in a JTree Component

   <source lang="java">
 

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

 public static void main(String[] argv) {
   JTree tree = new JTree() {
     protected void setExpandedState(TreePath path, boolean state) {
       if (state) {
         super.setExpandedState(path, state);
       }
     }
   };
 }

}


 </source>
   
  
 
  



Removing a Node to a JTree Component

   <source lang="java">
 

import java.util.Vector; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.text.Position; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.MutableTreeNode; import javax.swing.tree.TreePath; public class TreeNodeRemove{

 public static void main(String[] argv) {
   Vector<String> v = new Vector<String>();
   v.add("a");
   v.add("b");
   v.add("c");
   JTree tree = new JTree(v);
   DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
   int startRow = 0;
   String prefix = "b";
   TreePath path = tree.getNextMatch(prefix, startRow, Position.Bias.Forward);
   MutableTreeNode node = (MutableTreeNode) path.getLastPathComponent();
   model.removeNodeFromParent(node);
   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>
   
  
 
  



Returns a TreePath containing the specified node.

   <source lang="java">
 

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

 public TreePath getPath(TreeNode node) {
   List<TreeNode> list = new ArrayList<TreeNode>();
   while (node != null) {
     list.add(node);
     node = node.getParent();
   }
   Collections.reverse(list);
   return new TreePath(list.toArray());
 }

}


 </source>
   
  
 
  



Search backward from last visible row looking for any visible node whose name starts with prefix.

   <source lang="java">
 

import javax.swing.JTree; import javax.swing.text.Position; import javax.swing.tree.TreePath; public class Main {

 public static void main(String[] argv) throws Exception {
   JTree tree = new JTree();
   int startRow = tree.getRowCount() - 1;
   String prefix = "b";
   TreePath path = tree.getNextMatch(prefix, startRow, Position.Bias.Backward);
   System.out.println(path);
 }

}


 </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>
   
  
 
  



Set the Tree Line

   <source lang="java">
 

import java.awt.BorderLayout; import java.awt.Color; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.UIManager; public class TreeLineSample {

 public static void main(String args[]) {
   String title = "JTree Sample";
   JFrame frame = new JFrame(title);
   
   UIManager.put("Tree.line", Color.green);
   JTree tree = new JTree();
   tree.putClientProperty("JTree.lineStyle", "Horizontal");
   tree.setSelectionModel(null);
   JScrollPane scrollPane = new JScrollPane(tree);
   frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
   frame.setSize(300, 150);
   frame.setVisible(true);
 }

}


 </source>
   
  
 
  



Setting the Row Height of a JTree

   <source lang="java">
 

import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; public class TreeRowHeight {

 public static void main(String[] argv) {
   JTree tree = new JTree();
   tree.setRowHeight(15);
   JFrame frame = new JFrame("tree row height");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.add(new JScrollPane(tree));
   frame.setSize(380, 320);
   frame.setLocationRelativeTo(null);
   frame.setVisible(true);
 }

}


 </source>
   
  
 
  



Traverse all expanded nodes in tree

   <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 static void main(String[] argv) throws Exception {
   JTree tree = new JTree();
   visitAllExpandedNodes(tree);  
 }
 public static void visitAllExpandedNodes(JTree tree) {
   TreeNode root = (TreeNode) tree.getModel().getRoot();
   visitAllExpandedNodes(tree, new TreePath(root));
 }
 public static void visitAllExpandedNodes(JTree tree, TreePath parent) {
   if (!tree.isVisible(parent)) {
     return;
   }
   TreeNode node = (TreeNode) parent.getLastPathComponent();
   System.out.println(node);
   if (node.getChildCount() >= 0) {
     for (Enumeration e = node.children(); e.hasMoreElements();) {
       TreeNode n = (TreeNode) e.nextElement();
       TreePath path = parent.pathByAddingChild(n);
       visitAllExpandedNodes(tree, path);
     }
   }
 }

}


 </source>
   
  
 
  



Traverse Tree

   <source lang="java">
 

/* Definitive Guide to Swing for Java 2, Second Edition By John Zukowski ISBN: 1-893115-78-X Publisher: APress

  • /

import javax.swing.*; import javax.swing.event.*; import javax.swing.tree.*; import java.awt.*; import java.util.*; public class TraverseTree {

 public static void main(String args[]) {
   JFrame frame = new JFrame("Traverse Tree");
   Object footballNodes[] = { "Giants", "Jets", "Bills" };
   Vector footballVector = new NamedVector("Football", footballNodes);
   Object newYorkNodes[] = { "Mets", "Yankees", "Rangers", footballVector };
   Vector newYorkVector = new NamedVector("New York", newYorkNodes);
   Object bostonNodes[] = { "Red Sox", "Celtics", "Bruins" };
   Vector bostonVector = new NamedVector("Boston", bostonNodes);
   Object denverNodes[] = { "Rockies", "Avalanche", "Broncos" };
   Vector denverVector = new NamedVector("Denver", denverNodes);
   Object rootNodes[] = { newYorkVector, bostonVector, denverVector };
   Vector rootVector = new NamedVector("Root", rootNodes);
   JTree tree = new JTree(rootVector);
   tree.setRootVisible(true);
   TreeModel model = tree.getModel();
   Object rootObject = model.getRoot();
   if ((rootObject != null)
       && (rootObject instanceof DefaultMutableTreeNode)) {
     DefaultMutableTreeNode root = (DefaultMutableTreeNode) rootObject;
     //    printDescendents(root);
     Enumeration breadth = root.breadthFirstEnumeration();
     Enumeration depth = root.depthFirstEnumeration();
     Enumeration preOrder = root.preorderEnumeration();
     printEnumeration(breadth, "Breadth");
     //      printEnumeration(depth, "Depth");
     //      printEnumeration(preOrder, "Pre");
   }
   TreeSelectionListener treeSelectionListener = new TreeSelectionListener() {
     public void valueChanged(TreeSelectionEvent treeSelectionEvent) {
       JTree treeSource = (JTree) treeSelectionEvent.getSource();
       TreePath path = treeSource.getSelectionPath();
       System.out.println(path);
       System.out.println(path.getPath());
       System.out.println(path.getParentPath());
       System.out.println(((DefaultMutableTreeNode) path
           .getLastPathComponent()).getUserObject());
       System.out.println(path.getPathCount());
     }
   };
   tree.addTreeSelectionListener(treeSelectionListener);
   JScrollPane scrollPane = new JScrollPane(tree);
   frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
   frame.setSize(300, 400);
   frame.setVisible(true);
 }
 private static void printEnumeration(Enumeration e, String label) {
   System.out.println("-----" + label + "-----");
   while (e.hasMoreElements()) {
     System.out.println(e.nextElement());
   }
 }
 public static void printDescendents(TreeNode root) {
   System.out.println(root);
   Enumeration children = root.children();
   if (children != null) {
     while (children.hasMoreElements()) {
       printDescendents((TreeNode) children.nextElement());
     }
   }
 }

} class NamedVector extends Vector {

 String name;
 public NamedVector(String name) {
   this.name = name;
 }
 public NamedVector(String name, Object elements[]) {
   this.name = name;
   for (int i = 0, n = elements.length; i < n; i++) {
     add(elements[i]);
   }
 }
 public String toString() {
   return "[" + name + "]";
 }

}


 </source>
   
  
 
  



Tree based on Array structure

   <source lang="java">
 

import java.awt.BorderLayout; import java.util.Vector; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; public class TreeArraySample {

 public static void main(String args[]) {
   JFrame frame = new JFrame("JTreeSample");
   Vector oneVector = new NamedVector("One", args);
   Vector twoVector = new NamedVector("Two", new String[] { "Mercury",
       "Venus", "Mars" });
   Vector threeVector = new NamedVector("Three");
   threeVector.add(System.getProperties());
   threeVector.add(twoVector);
   Object rootNodes[] = { oneVector, twoVector, threeVector };
   Vector rootVector = new NamedVector("Root", rootNodes);
   JTree tree = new JTree(rootVector);
   JScrollPane scrollPane = new JScrollPane(tree);
   frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
   //    frame.getContentPane().add(tree, BorderLayout.CENTER);
   frame.setSize(300, 300);
   frame.setVisible(true);
 }

} class NamedVector extends Vector {

 String name;
 public NamedVector(String name) {
   this.name = name;
 }
 public NamedVector(String name, Object elements[]) {
   this.name = name;
   for (int i = 0, n = elements.length; i < n; i++) {
     add(elements[i]);
   }
 }
 public String toString() {
   return "[" + name + "]";
 }

}



 </source>
   
  
 
  



Tree: Drag and Drop

   <source lang="java">
 

/* Definitive Guide to Swing for Java 2, Second Edition By John Zukowski ISBN: 1-893115-78-X Publisher: APress

  • /

import java.awt.BorderLayout; import java.awt.Insets; import java.awt.Point; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.dnd.Autoscroll; import java.awt.dnd.DnDConstants; import java.awt.dnd.DragGestureEvent; import java.awt.dnd.DragGestureListener; import java.awt.dnd.DragSource; import java.awt.dnd.DragSourceContext; import java.awt.dnd.DragSourceDragEvent; import java.awt.dnd.DragSourceDropEvent; import java.awt.dnd.DragSourceEvent; import java.awt.dnd.DragSourceListener; import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetListener; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.util.Iterator; import java.util.List; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeModel; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; public class TreeTester {

 public static void main(String args[]) {
   JFrame f = new JFrame("Tree Dragging Tester");
   DndTree tree1 = new DndTree();
   JScrollPane leftPane = new JScrollPane(tree1);
   DndTree tree2 = new DndTree();
   JScrollPane rightPane = new JScrollPane(tree2);
   JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
       leftPane, rightPane);
   f.getContentPane().add(splitPane, BorderLayout.CENTER);
   f.setSize(300, 200);
   f.setVisible(true);
 }

} class DndTree extends JTree implements Autoscroll {

 private Insets insets;
 private int top = 0, bottom = 0, topRow = 0, bottomRow = 0;
 public DndTree() {
   DragSource dragSource = DragSource.getDefaultDragSource();
   dragSource
       .createDefaultDragGestureRecognizer(this,
           DnDConstants.ACTION_COPY_OR_MOVE,
           new TreeDragGestureListener());
   DropTarget dropTarget = new DropTarget(this,
       new TreeDropTargetListener());
 }
 public DndTree(TreeModel model) {
   super(model);
   DragSource dragSource = DragSource.getDefaultDragSource();
   dragSource
       .createDefaultDragGestureRecognizer(this,
           DnDConstants.ACTION_COPY_OR_MOVE,
           new TreeDragGestureListener());
   DropTarget dropTarget = new DropTarget(this,
       new TreeDropTargetListener());
 }
 public Insets getAutoscrollInsets() {
   return insets;
 }
 public void autoscroll(Point p) {
   // Only support up/down scrolling
   top = Math.abs(getLocation().y) + 10;
   bottom = top + getParent().getHeight() - 20;
   int next;
   if (p.y < top) {
     next = topRow--;
     bottomRow++;
     scrollRowToVisible(next);
   } else if (p.y > bottom) {
     next = bottomRow++;
     topRow--;
     scrollRowToVisible(next);
   }
 }
 private static class TreeDragGestureListener implements DragGestureListener {
   public void dragGestureRecognized(DragGestureEvent dragGestureEvent) {
     // Can only drag leafs
     JTree tree = (JTree) dragGestureEvent.getComponent();
     TreePath path = tree.getSelectionPath();
     if (path == null) {
       // Nothing selected, nothing to drag
       System.out.println("Nothing selected - beep");
       tree.getToolkit().beep();
     } else {
       DefaultMutableTreeNode selection = (DefaultMutableTreeNode) path
           .getLastPathComponent();
       if (selection.isLeaf()) {
         TransferableTreeNode node = new TransferableTreeNode(
             selection);
         dragGestureEvent.startDrag(DragSource.DefaultCopyDrop,
             node, new MyDragSourceListener());
       } else {
         System.out.println("Not a leaf - beep");
         tree.getToolkit().beep();
       }
     }
   }
 }
 private class TreeDropTargetListener implements DropTargetListener {
   public void dragEnter(DropTargetDragEvent dropTargetDragEvent) {
     // Setup positioning info for auto-scrolling
     top = Math.abs(getLocation().y);
     bottom = top + getParent().getHeight();
     topRow = getClosestRowForLocation(0, top);
     bottomRow = getClosestRowForLocation(0, bottom);
     insets = new Insets(top + 10, 0, bottom - 10, getWidth());
   }
   public void dragExit(DropTargetEvent dropTargetEvent) {
   }
   public void dragOver(DropTargetDragEvent dropTargetDragEvent) {
   }
   public void dropActionChanged(DropTargetDragEvent dropTargetDragEvent) {
   }
   public synchronized void drop(DropTargetDropEvent dropTargetDropEvent) {
     // Only support dropping over nodes that aren"t leafs
     Point location = dropTargetDropEvent.getLocation();
     TreePath path = getPathForLocation(location.x, location.y);
     Object node = path.getLastPathComponent();
     if ((node != null) && (node instanceof TreeNode)
         && (!((TreeNode) node).isLeaf())) {
       try {
         Transferable tr = dropTargetDropEvent.getTransferable();
         if (tr
             .isDataFlavorSupported(TransferableTreeNode.DEFAULT_MUTABLE_TREENODE_FLAVOR)) {
           dropTargetDropEvent
               .acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
           Object userObject = tr
               .getTransferData(TransferableTreeNode.DEFAULT_MUTABLE_TREENODE_FLAVOR);
           addElement(path, userObject);
           dropTargetDropEvent.dropComplete(true);
         } else if (tr
             .isDataFlavorSupported(DataFlavor.stringFlavor)) {
           dropTargetDropEvent
               .acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
           String string = (String) tr
               .getTransferData(DataFlavor.stringFlavor);
           addElement(path, string);
           dropTargetDropEvent.dropComplete(true);
         } else if (tr
             .isDataFlavorSupported(DataFlavor.plainTextFlavor)) {
           dropTargetDropEvent
               .acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
           Object stream = tr
               .getTransferData(DataFlavor.plainTextFlavor);
           if (stream instanceof InputStream) {
             InputStreamReader isr = new InputStreamReader(
                 (InputStream) stream);
             BufferedReader reader = new BufferedReader(isr);
             String line;
             while ((line = reader.readLine()) != null) {
               addElement(path, line);
             }
             dropTargetDropEvent.dropComplete(true);
           } else if (stream instanceof Reader) {
             BufferedReader reader = new BufferedReader(
                 (Reader) stream);
             String line;
             while ((line = reader.readLine()) != null) {
               addElement(path, line);
             }
             dropTargetDropEvent.dropComplete(true);
           } else {
             System.err.println("Unknown type: "
                 + stream.getClass());
             dropTargetDropEvent.rejectDrop();
           }
         } else if (tr
             .isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
           dropTargetDropEvent
               .acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
           List fileList = (List) tr
               .getTransferData(DataFlavor.javaFileListFlavor);
           Iterator iterator = fileList.iterator();
           while (iterator.hasNext()) {
             File file = (File) iterator.next();
             addElement(path, file.toURL());
           }
           dropTargetDropEvent.dropComplete(true);
         } else {
           System.err.println("Rejected");
           dropTargetDropEvent.rejectDrop();
         }
       } catch (IOException io) {
         io.printStackTrace();
         dropTargetDropEvent.rejectDrop();
       } catch (UnsupportedFlavorException ufe) {
         ufe.printStackTrace();
         dropTargetDropEvent.rejectDrop();
       }
     } else {
       System.out.println("Can"t drop on a leaf");
       dropTargetDropEvent.rejectDrop();
     }
   }
   private void addElement(TreePath path, Object element) {
     DefaultMutableTreeNode parent = (DefaultMutableTreeNode) path
         .getLastPathComponent();
     DefaultMutableTreeNode node = new DefaultMutableTreeNode(element);
     System.out.println("Added: " + node + " to " + parent);
     DefaultTreeModel model = (DefaultTreeModel) (DndTree.this
         .getModel());
     model.insertNodeInto(node, parent, parent.getChildCount());
   }
 }
 private static class MyDragSourceListener implements DragSourceListener {
   public void dragDropEnd(DragSourceDropEvent dragSourceDropEvent) {
     if (dragSourceDropEvent.getDropSuccess()) {
       int dropAction = dragSourceDropEvent.getDropAction();
       if (dropAction == DnDConstants.ACTION_MOVE) {
         System.out.println("MOVE: remove node");
       }
     }
   }
   public void dragEnter(DragSourceDragEvent dragSourceDragEvent) {
     DragSourceContext context = dragSourceDragEvent
         .getDragSourceContext();
     int dropAction = dragSourceDragEvent.getDropAction();
     if ((dropAction & DnDConstants.ACTION_COPY) != 0) {
       context.setCursor(DragSource.DefaultCopyDrop);
     } else if ((dropAction & DnDConstants.ACTION_MOVE) != 0) {
       context.setCursor(DragSource.DefaultMoveDrop);
     } else {
       context.setCursor(DragSource.DefaultCopyNoDrop);
     }
   }
   public void dragExit(DragSourceEvent dragSourceEvent) {
   }
   public void dragOver(DragSourceDragEvent dragSourceDragEvent) {
   }
   public void dropActionChanged(DragSourceDragEvent dragSourceDragEvent) {
   }
 }

} class TransferableTreeNode extends DefaultMutableTreeNode implements

   Transferable {
 final static int TREE = 0;
 final static int STRING = 1;
 final static int PLAIN_TEXT = 1;
 final public static DataFlavor DEFAULT_MUTABLE_TREENODE_FLAVOR = new DataFlavor(
     DefaultMutableTreeNode.class, "Default Mutable Tree Node");
 static DataFlavor flavors[] = { DEFAULT_MUTABLE_TREENODE_FLAVOR,
     DataFlavor.stringFlavor, DataFlavor.plainTextFlavor };
 private DefaultMutableTreeNode data;
 public TransferableTreeNode(DefaultMutableTreeNode data) {
   this.data = data;
 }
 public DataFlavor[] getTransferDataFlavors() {
   return flavors;
 }
 public Object getTransferData(DataFlavor flavor)
     throws UnsupportedFlavorException, IOException {
   Object returnObject;
   if (flavor.equals(flavors[TREE])) {
     Object userObject = data.getUserObject();
     if (userObject == null) {
       returnObject = data;
     } else {
       returnObject = userObject;
     }
   } else if (flavor.equals(flavors[STRING])) {
     Object userObject = data.getUserObject();
     if (userObject == null) {
       returnObject = data.toString();
     } else {
       returnObject = userObject.toString();
     }
   } else if (flavor.equals(flavors[PLAIN_TEXT])) {
     Object userObject = data.getUserObject();
     String string;
     if (userObject == null) {
       string = data.toString();
     } else {
       string = userObject.toString();
     }
     returnObject = new ByteArrayInputStream(string.getBytes("Unicode"));
   } else {
     throw new UnsupportedFlavorException(flavor);
   }
   return returnObject;
 }
 public boolean isDataFlavorSupported(DataFlavor flavor) {
   boolean returnValue = false;
   for (int i = 0, n = flavors.length; i < n; i++) {
     if (flavor.equals(flavors[i])) {
       returnValue = true;
       break;
     }
   }
   return returnValue;
 }

}


 </source>
   
  
 
  



Tree Expand Event Demo

   <source lang="java">
 

/* From http://java.sun.ru/docs/books/tutorial/index.html */ /*

* Copyright (c) 2006 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:
*
* -Redistribution of source code must retain the above copyright notice, this
*  list of conditions and the following disclaimer.
*
* -Redistribution 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, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed, licensed or intended
* for use in the design, construction, operation or maintenance of any
* nuclear facility.
*/

/*

* TreeExpandEventDemo.java is a 1.4 example that requires no other files.
*/

import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTree; import javax.swing.event.TreeExpansionEvent; import javax.swing.event.TreeExpansionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreeNode; public class TreeExpandEventDemo extends JPanel {

 DemoArea demoArea;
 JTextArea textArea;
 final static String newline = "\n";
 public TreeExpandEventDemo() {
   super(new GridBagLayout());
   GridBagLayout gridbag = (GridBagLayout) getLayout();
   GridBagConstraints c = new GridBagConstraints();
   c.fill = GridBagConstraints.BOTH;
   c.gridwidth = GridBagConstraints.REMAINDER;
   c.weightx = 1.0;
   c.weighty = 1.0;
   c.insets = new Insets(1, 1, 1, 1);
   demoArea = new DemoArea();
   gridbag.setConstraints(demoArea, c);
   add(demoArea);
   c.insets = new Insets(0, 0, 0, 0);
   textArea = new JTextArea();
   textArea.setEditable(false);
   JScrollPane scrollPane = new JScrollPane(textArea);
   scrollPane
       .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
   scrollPane.setPreferredSize(new Dimension(200, 75));
   gridbag.setConstraints(scrollPane, c);
   add(scrollPane);
   setPreferredSize(new Dimension(450, 450));
   setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
 }
 void saySomething(String eventDescription, TreeExpansionEvent e) {
   textArea.append(eventDescription + "; " + "path = " + e.getPath()
       + newline);
 }
 class DemoArea extends JScrollPane implements TreeExpansionListener {
   Dimension minSize = new Dimension(100, 100);
   JTree tree;
   public DemoArea() {
     TreeNode rootNode = createNodes();
     tree = new JTree(rootNode);
     tree.addTreeExpansionListener(this);
     setViewportView(tree);
   }
   private TreeNode createNodes() {
     DefaultMutableTreeNode root;
     DefaultMutableTreeNode grandparent;
     DefaultMutableTreeNode parent;
     DefaultMutableTreeNode child;
     root = new DefaultMutableTreeNode("San Francisco");
     grandparent = new DefaultMutableTreeNode("Potrero Hill");
     root.add(grandparent);
     //
     parent = new DefaultMutableTreeNode("Restaurants");
     grandparent.add(parent);
     child = new DefaultMutableTreeNode("Thai Barbeque");
     parent.add(child);
     child = new DefaultMutableTreeNode("Goat Hill Pizza");
     parent.add(child);
     //
     parent = new DefaultMutableTreeNode("Grocery Stores");
     grandparent.add(parent);
     child = new DefaultMutableTreeNode("Good Life Grocery");
     parent.add(child);
     child = new DefaultMutableTreeNode("Safeway");
     parent.add(child);
     grandparent = new DefaultMutableTreeNode("Noe Valley");
     root.add(grandparent);
     //
     parent = new DefaultMutableTreeNode("Restaurants");
     grandparent.add(parent);
     child = new DefaultMutableTreeNode("Hamano Sushi");
     parent.add(child);
     child = new DefaultMutableTreeNode("Hahn"s Hibachi");
     parent.add(child);
     //
     parent = new DefaultMutableTreeNode("Grocery Stores");
     grandparent.add(parent);
     child = new DefaultMutableTreeNode("Real Foods");
     parent.add(child);
     child = new DefaultMutableTreeNode("Bell Market");
     parent.add(child);
     return root;
   }
   public Dimension getMinimumSize() {
     return minSize;
   }
   public Dimension getPreferredSize() {
     return minSize;
   }
   // Required by TreeExpansionListener interface.
   public void treeExpanded(TreeExpansionEvent e) {
     saySomething("Tree-expanded event detected", e);
   }
   // Required by TreeExpansionListener interface.
   public void treeCollapsed(TreeExpansionEvent e) {
     saySomething("Tree-collapsed event detected", e);
   }
 }
 /**
  * Create the GUI and show it. For thread safety, this method should be
  * invoked from the event-dispatching thread.
  */
 private static void createAndShowGUI() {
   //Make sure we have nice window decorations.
   JFrame.setDefaultLookAndFeelDecorated(true);
   //Create and set up the window.
   JFrame frame = new JFrame("TreeExpandEventDemo");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   //Create and set up the content pane.
   JComponent newContentPane = new TreeExpandEventDemo();
   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();
     }
   });
 }

}


 </source>
   
  
 
  



Tree Expand Event Demo 2

   <source lang="java">
 

/* From http://java.sun.ru/docs/books/tutorial/index.html */ /*

* Copyright (c) 2006 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:
*
* -Redistribution of source code must retain the above copyright notice, this
*  list of conditions and the following disclaimer.
*
* -Redistribution 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, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed, licensed or intended
* for use in the design, construction, operation or maintenance of any
* nuclear facility.
*/

/*

* TreeExpandEventDemo2.java is a 1.4 example that requires no other files.
*/

import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTree; import javax.swing.event.TreeExpansionEvent; import javax.swing.event.TreeExpansionListener; import javax.swing.event.TreeWillExpandListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.ExpandVetoException; import javax.swing.tree.TreeNode; public class TreeExpandEventDemo2 extends JPanel {

 DemoArea demoArea;
 JTextArea textArea;
 final static String newline = "\n";
 public TreeExpandEventDemo2() {
   super(new GridBagLayout());
   GridBagLayout gridbag = (GridBagLayout) getLayout();
   GridBagConstraints c = new GridBagConstraints();
   c.fill = GridBagConstraints.BOTH;
   c.gridwidth = GridBagConstraints.REMAINDER;
   c.weightx = 1.0;
   c.weighty = 1.0;
   c.insets = new Insets(1, 1, 1, 1);
   demoArea = new DemoArea();
   gridbag.setConstraints(demoArea, c);
   add(demoArea);
   c.insets = new Insets(0, 0, 0, 0);
   textArea = new JTextArea();
   textArea.setEditable(false);
   JScrollPane scrollPane = new JScrollPane(textArea);
   scrollPane
       .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
   scrollPane.setPreferredSize(new Dimension(200, 75));
   gridbag.setConstraints(scrollPane, c);
   add(scrollPane);
   setPreferredSize(new Dimension(450, 450));
   setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
 }
 void saySomething(String eventDescription, TreeExpansionEvent e) {
   textArea.append(eventDescription + "; " + "path = " + e.getPath()
       + newline);
 }
 class DemoArea extends JScrollPane implements TreeExpansionListener,
     TreeWillExpandListener {
   Dimension minSize = new Dimension(100, 100);
   JTree tree;
   Object[] willExpandOptions = { "Cancel Expansion", "Expand" };
   String willExpandText = "A branch node is about to be expanded.\n"
       + "Click \"Cancel Expansion\" to prevent it.";
   String willExpandTitle = "Tree Will Expand";
   public DemoArea() {
     TreeNode rootNode = createNodes();
     tree = new JTree(rootNode);
     tree.addTreeExpansionListener(this);
     tree.addTreeWillExpandListener(this);
     setViewportView(tree);
   }
   private TreeNode createNodes() {
     DefaultMutableTreeNode root;
     DefaultMutableTreeNode grandparent;
     DefaultMutableTreeNode parent;
     DefaultMutableTreeNode child;
     root = new DefaultMutableTreeNode("San Francisco");
     grandparent = new DefaultMutableTreeNode("Potrero Hill");
     root.add(grandparent);
     //
     parent = new DefaultMutableTreeNode("Restaurants");
     grandparent.add(parent);
     child = new DefaultMutableTreeNode("Thai Barbeque");
     parent.add(child);
     child = new DefaultMutableTreeNode("Goat Hill Pizza");
     parent.add(child);
     //
     parent = new DefaultMutableTreeNode("Grocery Stores");
     grandparent.add(parent);
     child = new DefaultMutableTreeNode("Good Life Grocery");
     parent.add(child);
     child = new DefaultMutableTreeNode("Safeway");
     parent.add(child);
     grandparent = new DefaultMutableTreeNode("Noe Valley");
     root.add(grandparent);
     //
     parent = new DefaultMutableTreeNode("Restaurants");
     grandparent.add(parent);
     child = new DefaultMutableTreeNode("Hamano Sushi");
     parent.add(child);
     child = new DefaultMutableTreeNode("Hahn"s Hibachi");
     parent.add(child);
     //
     parent = new DefaultMutableTreeNode("Grocery Stores");
     grandparent.add(parent);
     child = new DefaultMutableTreeNode("Real Foods");
     parent.add(child);
     child = new DefaultMutableTreeNode("Bell Market");
     parent.add(child);
     return root;
   }
   public Dimension getMinimumSize() {
     return minSize;
   }
   public Dimension getPreferredSize() {
     return minSize;
   }
   //Required by TreeWillExpandListener interface.
   public void treeWillExpand(TreeExpansionEvent e)
       throws ExpandVetoException {
     saySomething("Tree-will-expand event detected", e);
     int n = JOptionPane.showOptionDialog(this, willExpandText,
         willExpandTitle, JOptionPane.YES_NO_OPTION,
         JOptionPane.QUESTION_MESSAGE, null, willExpandOptions,
         willExpandOptions[1]);
     if (n == 0) {
       //User said cancel expansion.
       saySomething("Tree expansion cancelled", e);
       throw new ExpandVetoException(e);
     }
   }
   //Required by TreeWillExpandListener interface.
   public void treeWillCollapse(TreeExpansionEvent e) {
     saySomething("Tree-will-collapse event detected", e);
   }
   // Required by TreeExpansionListener interface.
   public void treeExpanded(TreeExpansionEvent e) {
     saySomething("Tree-expanded event detected", e);
   }
   // Required by TreeExpansionListener interface.
   public void treeCollapsed(TreeExpansionEvent e) {
     saySomething("Tree-collapsed event detected", e);
   }
 }
 /**
  * Create the GUI and show it. For thread safety, this method should be
  * invoked from the event-dispatching thread.
  */
 private static void createAndShowGUI() {
   //Make sure we have nice window decorations.
   JFrame.setDefaultLookAndFeelDecorated(true);
   //Create and set up the window.
   JFrame frame = new JFrame("TreeExpandEventDemo2");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   //Create and set up the content pane.
   JComponent newContentPane = new TreeExpandEventDemo2();
   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();
     }
   });
 }

}


 </source>
   
  
 
  



TreeExpansionListener and TreeExpansionEvent

   <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.
*/

/*

* TreeExpandEventDemo.java requires no other files.
*/

import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTree; import javax.swing.event.TreeExpansionEvent; import javax.swing.event.TreeExpansionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreeNode; public class TreeExpandEventDemo extends JPanel {

 DemoArea demoArea;
 JTextArea textArea;
 final static String newline = "\n";
 public TreeExpandEventDemo() {
   super(new GridBagLayout());
   GridBagLayout gridbag = (GridBagLayout) getLayout();
   GridBagConstraints c = new GridBagConstraints();
   c.fill = GridBagConstraints.BOTH;
   c.gridwidth = GridBagConstraints.REMAINDER;
   c.weightx = 1.0;
   c.weighty = 1.0;
   c.insets = new Insets(1, 1, 1, 1);
   demoArea = new DemoArea();
   gridbag.setConstraints(demoArea, c);
   add(demoArea);
   c.insets = new Insets(0, 0, 0, 0);
   textArea = new JTextArea();
   textArea.setEditable(false);
   JScrollPane scrollPane = new JScrollPane(textArea);
   scrollPane
       .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
   scrollPane.setPreferredSize(new Dimension(200, 75));
   gridbag.setConstraints(scrollPane, c);
   add(scrollPane);
   setPreferredSize(new Dimension(450, 450));
   setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
 }
 void saySomething(String eventDescription, TreeExpansionEvent e) {
   textArea
       .append(eventDescription + "; " + "path = " + e.getPath() + newline);
 }
 class DemoArea extends JScrollPane implements TreeExpansionListener {
   Dimension minSize = new Dimension(100, 100);
   JTree tree;
   public DemoArea() {
     TreeNode rootNode = createNodes();
     tree = new JTree(rootNode);
     tree.addTreeExpansionListener(this);
     setViewportView(tree);
   }
   private TreeNode createNodes() {
     DefaultMutableTreeNode root;
     DefaultMutableTreeNode grandparent;
     DefaultMutableTreeNode parent;
     DefaultMutableTreeNode child;
     root = new DefaultMutableTreeNode("San Francisco");
     grandparent = new DefaultMutableTreeNode("Potrero Hill");
     root.add(grandparent);
     //
     parent = new DefaultMutableTreeNode("Restaurants");
     grandparent.add(parent);
     child = new DefaultMutableTreeNode("Thai Barbeque");
     parent.add(child);
     child = new DefaultMutableTreeNode("Goat Hill Pizza");
     parent.add(child);
     //
     parent = new DefaultMutableTreeNode("Grocery Stores");
     grandparent.add(parent);
     child = new DefaultMutableTreeNode("Good Life Grocery");
     parent.add(child);
     child = new DefaultMutableTreeNode("Safeway");
     parent.add(child);
     grandparent = new DefaultMutableTreeNode("Noe Valley");
     root.add(grandparent);
     //
     parent = new DefaultMutableTreeNode("Restaurants");
     grandparent.add(parent);
     child = new DefaultMutableTreeNode("Hamano Sushi");
     parent.add(child);
     child = new DefaultMutableTreeNode("Hahn"s Hibachi");
     parent.add(child);
     //
     parent = new DefaultMutableTreeNode("Grocery Stores");
     grandparent.add(parent);
     child = new DefaultMutableTreeNode("Real Foods");
     parent.add(child);
     child = new DefaultMutableTreeNode("Bell Market");
     parent.add(child);
     return root;
   }
   public Dimension getMinimumSize() {
     return minSize;
   }
   public Dimension getPreferredSize() {
     return minSize;
   }
   // Required by TreeExpansionListener interface.
   public void treeExpanded(TreeExpansionEvent e) {
     saySomething("Tree-expanded event detected", e);
   }
   // Required by TreeExpansionListener interface.
   public void treeCollapsed(TreeExpansionEvent e) {
     saySomething("Tree-collapsed event detected", e);
   }
 }
 /**
  * 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("TreeExpandEventDemo");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   // Create and set up the content pane.
   JComponent newContentPane = new TreeExpandEventDemo();
   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();
     }
   });
 }

}


 </source>
   
  
 
  



Tree Icon Demo

   <source lang="java">
 

/* From http://java.sun.ru/docs/books/tutorial/index.html */ /*

* Copyright (c) 2006 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:
*
* -Redistribution of source code must retain the above copyright notice, this
*  list of conditions and the following disclaimer.
*
* -Redistribution 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, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed, licensed or intended
* for use in the design, construction, operation or maintenance of any
* nuclear facility.
*/

/**

* 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 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.tree.DefaultMutableTreeNode; import javax.swing.tree.TreeSelectionModel; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.ImageIcon; import java.net.URL; import java.io.IOException; import java.awt.Dimension; import java.awt.GridLayout; public class TreeIconDemo extends JPanel

                         implements TreeSelectionListener {
   private JEditorPane htmlPane;
   private JTree tree;
   private URL helpURL;
   private static boolean DEBUG = false;
   public TreeIconDemo() {
       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);
       //Set the icon for leaf nodes.
       ImageIcon leafIcon = createImageIcon("images/middle.gif");
       if (leafIcon != null) {
           DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
           renderer.setLeafIcon(leafIcon);
           tree.setCellRenderer(renderer);
       } else {
           System.err.println("Leaf 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 = TreeIconDemo.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 = TreeIconDemo.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 = TreeIconDemo.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() {
       //Make sure we have nice window decorations.
       JFrame.setDefaultLookAndFeelDecorated(true);
       //Create and set up the window.
       JFrame frame = new JFrame("TreeIconDemo");
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       //Create and set up the content pane.
       TreeIconDemo newContentPane = new TreeIconDemo();
       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();
           }
       });
   }

}



 </source>
   
  
 
  



Tree Lines

   <source lang="java">
 

import java.awt.BorderLayout; import java.awt.Container; import javax.swing.Box; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; public class TreeLines {

 public static void main(String args[]) {
   JFrame frame = new JFrame("Tree Lines");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   Container content = frame.getContentPane();
   Box box = Box.createHorizontalBox();
   JTree tree1 = new JTree();
   tree1.putClientProperty("JTree.lineStyle", "Angled");
   JScrollPane scrollPane1 = new JScrollPane(tree1);
   tree1.setAutoscrolls(true);
   JTree tree2 = new JTree();
   JScrollPane scrollPane2 = new JScrollPane(tree2);
   box.add(scrollPane1, BorderLayout.WEST);
   box.add(scrollPane2, BorderLayout.EAST);
   frame.getContentPane().add(box, BorderLayout.CENTER);
   frame.setSize(300, 240);
   frame.setVisible(true);
 }

}


 </source>
   
  
 
  



Tree open Icon

   <source lang="java">
 

/* Definitive Guide to Swing for Java 2, Second Edition By John Zukowski ISBN: 1-893115-78-X Publisher: APress

  • /

import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.LookAndFeel; import javax.swing.UIDefaults; import javax.swing.UIManager; public class LazySample {

 public static void main(String args[]) {
   JFrame frame = new JFrame("Lazy Example");
   Object iconObject = LookAndFeel.makeIcon(LazySample.class, "World.gif");
   UIManager.put("Tree.leafIcon", iconObject);
   Integer fifteen = new Integer(15);
   Object lazyArgs[] = new Object[] { Color.green, Boolean.TRUE, fifteen,
       fifteen };
   Object lazyDiamond = new UIDefaults.ProxyLazyValue("DiamondIcon",
       lazyArgs);
   UIManager.put("Tree.openIcon", lazyDiamond);
   JTree tree = new JTree();
   JScrollPane scrollPane = new JScrollPane(tree);
   Container contentPane = frame.getContentPane();
   contentPane.add(scrollPane, BorderLayout.CENTER);
   frame.setSize(200, 200);
   frame.setVisible(true);
 }

}


 </source>
   
  
 
  



Tree Selection Row

   <source lang="java">
 

import java.awt.BorderLayout; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; public class TreeSelectionRow {

 public static void main(String args[]) {
   String title = "JTree Sample";
   JFrame frame = new JFrame(title);
   JTree tree = new JTree();
   TreeSelectionListener treeSelectionListener = new TreeSelectionListener() {
     public void valueChanged(TreeSelectionEvent treeSelectionEvent) {
       JTree treeSource = (JTree) treeSelectionEvent.getSource();
       System.out.println("Min: " + treeSource.getMinSelectionRow());
       System.out.println("Max: " + treeSource.getMaxSelectionRow());
       System.out.println("Lead: " + treeSource.getLeadSelectionRow());
       System.out.println("Row: " + treeSource.getSelectionRows()[0]);
     }
   };
   tree.addTreeSelectionListener(treeSelectionListener);
   JScrollPane scrollPane = new JScrollPane(tree);
   frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
   frame.setSize(300, 150);
   frame.setVisible(true);
 }

}


 </source>
   
  
 
  



Tree will Expand event and listener

   <source lang="java">
 

import java.awt.BorderLayout; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.event.TreeExpansionEvent; import javax.swing.event.TreeWillExpandListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.ExpandVetoException; import javax.swing.tree.TreePath; public class TreeExpandSample {

 public static void main(String args[]) {
   String title = ("JTree Expand Sample");
   JFrame frame = new JFrame(title);
   JTree tree = new JTree();
   TreeWillExpandListener treeWillExpandListener = new TreeWillExpandListener() {
     public void treeWillCollapse(TreeExpansionEvent treeExpansionEvent)
         throws ExpandVetoException {
       TreePath path = treeExpansionEvent.getPath();
       DefaultMutableTreeNode node = (DefaultMutableTreeNode) path
           .getLastPathComponent();
       String data = node.getUserObject().toString();
       if (data.equals("colors")) {
         throw new ExpandVetoException(treeExpansionEvent);
       }
     }
     public void treeWillExpand(TreeExpansionEvent treeExpansionEvent)
         throws ExpandVetoException {
       TreePath path = treeExpansionEvent.getPath();
       DefaultMutableTreeNode node = (DefaultMutableTreeNode) path
           .getLastPathComponent();
       String data = node.getUserObject().toString();
       if (data.equals("sports")) {
         throw new ExpandVetoException(treeExpansionEvent);
       }
     }
   };
   tree.addTreeWillExpandListener(treeWillExpandListener);
   JScrollPane scrollPane = new JScrollPane(tree);
   frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
   frame.setSize(300, 150);
   frame.setVisible(true);
 }

}


 </source>
   
  
 
  



Use UIManager to change the default icon for JTree

   <source lang="java">
 

import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.UIManager; public class Main {

 public static void main(String[] argv) throws Exception {
   Icon leafIcon = new ImageIcon("leaf.gif");
   Icon openIcon = new ImageIcon("open.gif");
   Icon closedIcon = new ImageIcon("closed.gif");
   UIManager.put("Tree.leafIcon", leafIcon);
   UIManager.put("Tree.openIcon", openIcon);
   UIManager.put("Tree.closedIcon", closedIcon);
   
   JTree tree = new JTree();
   JFrame f = new JFrame();
   f.add(new JScrollPane(tree));
   f.setSize(300, 300);
   f.setVisible(true);
 }

}


 </source>
   
  
 
  



Visiting All the Nodes in a JTree Component

   <source lang="java">
 

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

 public static void main(String[] argv) throws Exception {
   JTree tree = new JTree();
   visitAllNodes(tree);
 }
 public static void visitAllNodes(JTree tree) {
   TreeNode root = (TreeNode) tree.getModel().getRoot();
   visitAllNodes(root);
 }
 public static void visitAllNodes(TreeNode node) {
   System.out.println(node);
   if (node.getChildCount() >= 0) {
     for (Enumeration e = node.children(); e.hasMoreElements();) {
       TreeNode n = (TreeNode) e.nextElement();
       visitAllNodes(n);
     }
   }
 }

}


 </source>