Java/Swing Components/Tree

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

Animated Icon Tree Example

// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html
/* (swing1.1.1beta2) */

import java.awt.BorderLayout;
import java.awt.ruponent;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.ImageObserver;
import java.util.Hashtable;
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.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
/**
 * @version 1.0 06/20/99
 */
public class AnimatedIconTreeExample extends JFrame {
  public AnimatedIconTreeExample() {
    super("AnimatedIconTreeExample");
    String[] strs = { "CARNIVORA", // 0
        "Felidae", // 1
        "Acinonyx jutatus  (cheetah)", // 2
        "Panthera leo  (lion)", // 3
        "Canidae", // 4
        "Canis lupus  (wolf)", // 5
        "Lycaon pictus  (lycaon)", // 6
        "Vulpes Vulpes  (fox)" }; // 7
    IconNode[] nodes = new IconNode[strs.length];
    for (int i = 0; i < strs.length; i++) {
      nodes[i] = new IconNode(strs[i]);
    }
    nodes[0].add(nodes[1]);
    nodes[0].add(nodes[4]);
    nodes[1].add(nodes[2]);
    nodes[1].add(nodes[3]);
    nodes[4].add(nodes[5]);
    nodes[4].add(nodes[6]);
    nodes[4].add(nodes[7]);
    nodes[2].setIcon(new ImageIcon("jexpAnimation.gif"));
    nodes[3].setIcon(new ImageIcon("jexpAnimation.gif"));
    nodes[5].setIcon(new ImageIcon("jexpAnimation.gif"));
    nodes[6].setIcon(new ImageIcon("jexpAnimation.gif"));
    nodes[7].setIcon(new ImageIcon("jexpAnimation.gif"));
    JTree tree = new JTree(nodes[0]);
    tree.setCellRenderer(new IconNodeRenderer());
    setImageObserver(tree, nodes);
    JScrollPane sp = new JScrollPane(tree);
    getContentPane().add(sp, BorderLayout.CENTER);
  }
  private void setImageObserver(JTree tree, IconNode[] nodes) {
    for (int i = 0; i < nodes.length; i++) {
      ImageIcon icon = (ImageIcon) nodes[i].getIcon();
      if (icon != null) {
        icon.setImageObserver(new NodeImageObserver(tree, nodes[i]));
      }
    }
  }
  class NodeImageObserver implements ImageObserver {
    JTree tree;
    DefaultTreeModel model;
    TreeNode node;
    NodeImageObserver(JTree tree, TreeNode node) {
      this.tree = tree;
      this.model = (DefaultTreeModel) tree.getModel();
      this.node = node;
    }
    public boolean imageUpdate(Image img, int flags, int x, int y, int w,
        int h) {
      if ((flags & (FRAMEBITS | ALLBITS)) != 0) {
        TreePath path = new TreePath(model.getPathToRoot(node));
        Rectangle rect = tree.getPathBounds(path);
        if (rect != null) {
          tree.repaint(rect);
        }
      }
      return (flags & (ALLBITS | ABORT)) == 0;
    }
  }
  public static void main(String args[]) {
    try {
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    } catch (Exception evt) {}
  
    AnimatedIconTreeExample frame = new AnimatedIconTreeExample();
    frame.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    frame.setSize(280, 200);
    frame.setVisible(true);
  }
}
class IconNodeRenderer extends DefaultTreeCellRenderer {
  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);
    Icon icon = ((IconNode) value).getIcon();
    if (icon == null) {
      Hashtable icons = (Hashtable) tree.getClientProperty("JTree.icons");
      String name = ((IconNode) value).getIconName();
      if ((icons != null) && (name != null)) {
        icon = (Icon) icons.get(name);
        if (icon != null) {
          setIcon(icon);
        }
      }
    } else {
      setIcon(icon);
    }
    return this;
  }
}
class IconNode extends DefaultMutableTreeNode {
  protected Icon icon;
  protected String iconName;
  public IconNode() {
    this(null);
  }
  public IconNode(Object userObject) {
    this(userObject, true, null);
  }
  public IconNode(Object userObject, boolean allowsChildren, Icon icon) {
    super(userObject, allowsChildren);
    this.icon = icon;
  }
  public void setIcon(Icon icon) {
    this.icon = icon;
  }
  public Icon getIcon() {
    return icon;
  }
  public String getIconName() {
    if (iconName != null) {
      return iconName;
    } else {
      String str = userObject.toString();
      int index = str.lastIndexOf(".");
      if (index != -1) {
        return str.substring(++index);
      } else {
        return null;
      }
    }
  }
  public void setIconName(String name) {
    iconName = name;
  }
}





Animated Icon Tree Example 2

// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html

import java.awt.BorderLayout;
import java.awt.ruponent;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.ImageObserver;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
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.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
/**
 * @version 1.0 06/20/99
 */
public class AnimatedIconTreeExample2 extends JFrame {
  final static String CAT = "cat";
  final static String DOG = "dog";
  public AnimatedIconTreeExample2() {
    super("AnimatedIconTreeExample2");
    String[] strs = { "CARNIVORA", // 0
        "Felidae", // 1
        "Acinonyx jutatus  (cheetah)", // 2
        "Panthera leo  (lion)", // 3
        "Canidae", // 4
        "Canis lupus  (wolf)", // 5
        "Lycaon pictus  (lycaon)", // 6
        "Vulpes Vulpes  (fox)" }; // 7
    IconNode[] nodes = new IconNode[strs.length];
    for (int i = 0; i < strs.length; i++) {
      nodes[i] = new IconNode(strs[i]);
    }
    nodes[0].add(nodes[1]);
    nodes[0].add(nodes[4]);
    nodes[1].add(nodes[2]);
    nodes[1].add(nodes[3]);
    nodes[4].add(nodes[5]);
    nodes[4].add(nodes[6]);
    nodes[4].add(nodes[7]);
    // If you want to share the ImageIcon with a node.
    nodes[2].setIconName(CAT);
    nodes[3].setIconName(CAT);
    nodes[5].setIconName(DOG);
    nodes[6].setIconName(DOG);
    nodes[7].setIconName(DOG);
    Hashtable icons = new Hashtable();
    icons.put(CAT, new ImageIcon("jexpAnimation.gif"));
    icons.put(DOG, new ImageIcon("jexpAnimation.gif"));
    JTree tree = new JTree(nodes[0]);
    tree.putClientProperty("JTree.icons", icons);
    tree.setCellRenderer(new IconNodeRenderer());
    setImageObserver(tree, nodes, icons);
    JScrollPane sp = new JScrollPane(tree);
    getContentPane().add(sp, BorderLayout.CENTER);
  }
  private void setImageObserver(JTree tree, IconNode[] nodes, Hashtable icons) {
    Hashtable observers = new Hashtable();
    for (int i = 0; i < nodes.length; i++) {
      ImageIcon icon = (ImageIcon) nodes[i].getIcon();
      if (icon != null) {
        Vector repaintNodes = new Vector();
        repaintNodes.addElement(nodes[i]);
        icon
            .setImageObserver(new NodeImageObserver(tree,
                repaintNodes));
      } else {
        String iconName = nodes[i].getIconName();
        if (iconName != null) {
          Vector repaintNodes = (Vector) observers.get(iconName);
          if (repaintNodes == null) {
            repaintNodes = new Vector();
            observers.put(iconName, repaintNodes);
          }
          repaintNodes.addElement(nodes[i]);
        }
      }
    }
    Enumeration e = observers.keys();
    while (e.hasMoreElements()) {
      String iconName = (String) e.nextElement();
      Vector repaintNodes = (Vector) observers.get(iconName);
      ImageIcon icon = (ImageIcon) icons.get(iconName);
      icon.setImageObserver(new NodeImageObserver(tree, repaintNodes));
    }
  }
  class NodeImageObserver implements ImageObserver {
    JTree tree;
    DefaultTreeModel model;
    Vector nodes;
    NodeImageObserver(JTree tree, Vector nodes) {
      this.tree = tree;
      this.model = (DefaultTreeModel) tree.getModel();
      this.nodes = nodes;
    }
    public boolean imageUpdate(Image img, int flags, int x, int y, int w,
        int h) {
      if ((flags & (FRAMEBITS | ALLBITS)) != 0) {
        Enumeration e = nodes.elements();
        while (e.hasMoreElements()) {
          TreeNode node = (TreeNode) e.nextElement();
          TreePath path = new TreePath(model.getPathToRoot(node));
          Rectangle rect = tree.getPathBounds(path);
          if (rect != null) {
            tree.repaint(rect);
          }
        }
      }
      return (flags & (ALLBITS | ABORT)) == 0;
    }
  }
  public static void main(String args[]) {
    try {
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    } catch (Exception evt) {}
  
    AnimatedIconTreeExample2 frame = new AnimatedIconTreeExample2();
    frame.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    frame.setSize(280, 200);
    frame.setVisible(true);
  }
}
class IconNodeRenderer extends DefaultTreeCellRenderer {
  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);
    Icon icon = ((IconNode) value).getIcon();
    if (icon == null) {
      Hashtable icons = (Hashtable) tree.getClientProperty("JTree.icons");
      String name = ((IconNode) value).getIconName();
      if ((icons != null) && (name != null)) {
        icon = (Icon) icons.get(name);
        if (icon != null) {
          setIcon(icon);
        }
      }
    } else {
      setIcon(icon);
    }
    return this;
  }
}
class IconNode extends DefaultMutableTreeNode {
  protected Icon icon;
  protected String iconName;
  public IconNode() {
    this(null);
  }
  public IconNode(Object userObject) {
    this(userObject, true, null);
  }
  public IconNode(Object userObject, boolean allowsChildren, Icon icon) {
    super(userObject, allowsChildren);
    this.icon = icon;
  }
  public void setIcon(Icon icon) {
    this.icon = icon;
  }
  public Icon getIcon() {
    return icon;
  }
  public String getIconName() {
    if (iconName != null) {
      return iconName;
    } else {
      String str = userObject.toString();
      int index = str.lastIndexOf(".");
      if (index != -1) {
        return str.substring(++index);
      } else {
        return null;
      }
    }
  }
  public void setIconName(String name) {
    iconName = name;
  }
}





Checkbox Node Tree Example

// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ruponent;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
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 java.util.Enumeration;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.border.TitledBorder;
import javax.swing.plaf.ColorUIResource;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

/**
 * @version 1.1 01/15/99
 */
public class CheckNodeTreeExample extends JFrame {
  
  public CheckNodeTreeExample() {
    super("CheckNode TreeExample");
    String[] strs = {"swing",     // 0
         "platf",     // 1
         "basic",     // 2
         "metal",     // 3
         "JTree"};    // 4
                                             
    CheckNode[] nodes = new CheckNode[strs.length];
    for (int i=0;i<strs.length;i++) {
      nodes[i] = new CheckNode(strs[i]); 
    }
    nodes[0].add(nodes[1]);
    nodes[1].add(nodes[2]);
    nodes[1].add(nodes[3]);
    nodes[0].add(nodes[4]);
    nodes[3].setSelected(true);
    JTree tree = new JTree( nodes[0] );
    tree.setCellRenderer(new CheckRenderer());
    tree.getSelectionModel().setSelectionMode(
      TreeSelectionModel.SINGLE_TREE_SELECTION
    );
    tree.putClientProperty("JTree.lineStyle", "Angled");
    tree.addMouseListener(new NodeSelectionListener(tree));
    JScrollPane sp = new JScrollPane(tree);
    
    ModePanel mp = new ModePanel(nodes);
    JTextArea textArea = new JTextArea(3,10);
    JScrollPane textPanel = new JScrollPane(textArea);
    JButton button = new JButton("print");
    button.addActionListener(
      new ButtonActionListener(nodes[0], textArea));
    JPanel panel = new JPanel(new BorderLayout());
    panel.add(mp,     BorderLayout.CENTER);
    panel.add(button, BorderLayout.SOUTH);
    
    getContentPane().add(sp,    BorderLayout.CENTER);
    getContentPane().add(panel, BorderLayout.EAST);
    getContentPane().add(textPanel, BorderLayout.SOUTH);
  }
  class NodeSelectionListener extends MouseAdapter {
    JTree tree;
    
    NodeSelectionListener(JTree tree) {
      this.tree = tree;
    }
    
    public void mouseClicked(MouseEvent e) {
      int x = e.getX();
      int y = e.getY();
      int row = tree.getRowForLocation(x, y);
      TreePath  path = tree.getPathForRow(row);
      //TreePath  path = tree.getSelectionPath();
      if (path != null) {
        CheckNode node = (CheckNode)path.getLastPathComponent();
        boolean isSelected = ! (node.isSelected());
        node.setSelected(isSelected);
        if (node.getSelectionMode() == CheckNode.DIG_IN_SELECTION) {
          if ( isSelected) {
            tree.expandPath(path);
          } else {
            tree.collapsePath(path);
          }
        }
        ((DefaultTreeModel) tree.getModel()).nodeChanged(node);
        // I need revalidate if node is root.  but why?
        if (row == 0) {
          tree.revalidate();
          tree.repaint();
        }
      }
    }
  }
  class ModePanel extends JPanel implements ActionListener {
    CheckNode[] nodes;
    JRadioButton b_single, b_dig_in;
    ModePanel(CheckNode[] nodes) {
      this.nodes = nodes;
      setLayout(new GridLayout(2, 1));
      setBorder(new TitledBorder("Check Mode"));
      ButtonGroup group = new ButtonGroup();
      add(b_dig_in = new JRadioButton("DIG_IN  "));
      add(b_single = new JRadioButton("SINGLE  "));
      group.add(b_dig_in);
      group.add(b_single);
      b_dig_in.addActionListener(this);
      b_single.addActionListener(this);
      b_dig_in.setSelected(true);
    }
    public void actionPerformed(ActionEvent e) {
      int mode;
      if (b_single == e.getSource()) {
        mode = CheckNode.SINGLE_SELECTION;
      } else {
        mode = CheckNode.DIG_IN_SELECTION;
      }
      for (int i = 0; i < nodes.length; i++) {
        nodes[i].setSelectionMode(mode);
      }
    }
  }
  class ButtonActionListener implements ActionListener {
    CheckNode root;
    JTextArea textArea;
    ButtonActionListener(final CheckNode root, final JTextArea textArea) {
      this.root = root;
      this.textArea = textArea;
    }
    public void actionPerformed(ActionEvent ev) {
      Enumeration e = root.breadthFirstEnumeration();
      while (e.hasMoreElements()) {
        CheckNode node = (CheckNode) e.nextElement();
        if (node.isSelected()) {
          TreeNode[] nodes = node.getPath();
          textArea.append("\n" + nodes[0].toString());
          for (int i = 1; i < nodes.length; i++) {
            textArea.append("/" + nodes[i].toString());
          }
        }
      }
    }
  }
  public static void main(String args[]) {
    try {
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    } catch (Exception evt) {}
  
    CheckNodeTreeExample frame = new CheckNodeTreeExample();
    frame.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    frame.setSize(300, 200);
    frame.setVisible(true);
  }
}
class CheckRenderer extends JPanel implements TreeCellRenderer {
  protected JCheckBox check;
  protected TreeLabel label;
  public CheckRenderer() {
    setLayout(null);
    add(check = new JCheckBox());
    add(label = new TreeLabel());
    check.setBackground(UIManager.getColor("Tree.textBackground"));
    label.setForeground(UIManager.getColor("Tree.textForeground"));
  }
  public Component getTreeCellRendererComponent(JTree tree, Object value,
      boolean isSelected, boolean expanded, boolean leaf, int row,
      boolean hasFocus) {
    String stringValue = tree.convertValueToText(value, isSelected,
        expanded, leaf, row, hasFocus);
    setEnabled(tree.isEnabled());
    check.setSelected(((CheckNode) value).isSelected());
    label.setFont(tree.getFont());
    label.setText(stringValue);
    label.setSelected(isSelected);
    label.setFocus(hasFocus);
    if (leaf) {
      label.setIcon(UIManager.getIcon("Tree.leafIcon"));
    } else if (expanded) {
      label.setIcon(UIManager.getIcon("Tree.openIcon"));
    } else {
      label.setIcon(UIManager.getIcon("Tree.closedIcon"));
    }
    return this;
  }
  public Dimension getPreferredSize() {
    Dimension d_check = check.getPreferredSize();
    Dimension d_label = label.getPreferredSize();
    return new Dimension(d_check.width + d_label.width,
        (d_check.height < d_label.height ? d_label.height
            : d_check.height));
  }
  public void doLayout() {
    Dimension d_check = check.getPreferredSize();
    Dimension d_label = label.getPreferredSize();
    int y_check = 0;
    int y_label = 0;
    if (d_check.height < d_label.height) {
      y_check = (d_label.height - d_check.height) / 2;
    } else {
      y_label = (d_check.height - d_label.height) / 2;
    }
    check.setLocation(0, y_check);
    check.setBounds(0, y_check, d_check.width, d_check.height);
    label.setLocation(d_check.width, y_label);
    label.setBounds(d_check.width, y_label, d_label.width, d_label.height);
  }
  public void setBackground(Color color) {
    if (color instanceof ColorUIResource)
      color = null;
    super.setBackground(color);
  }
  public class TreeLabel extends JLabel {
    boolean isSelected;
    boolean hasFocus;
    public TreeLabel() {
    }
    public void setBackground(Color color) {
      if (color instanceof ColorUIResource)
        color = null;
      super.setBackground(color);
    }
    public void paint(Graphics g) {
      String str;
      if ((str = getText()) != null) {
        if (0 < str.length()) {
          if (isSelected) {
            g.setColor(UIManager
                .getColor("Tree.selectionBackground"));
          } else {
            g.setColor(UIManager.getColor("Tree.textBackground"));
          }
          Dimension d = getPreferredSize();
          int imageOffset = 0;
          Icon currentI = getIcon();
          if (currentI != null) {
            imageOffset = currentI.getIconWidth()
                + Math.max(0, getIconTextGap() - 1);
          }
          g.fillRect(imageOffset, 0, d.width - 1 - imageOffset,
              d.height);
          if (hasFocus) {
            g.setColor(UIManager
                .getColor("Tree.selectionBorderColor"));
            g.drawRect(imageOffset, 0, d.width - 1 - imageOffset,
                d.height - 1);
          }
        }
      }
      super.paint(g);
    }
    public Dimension getPreferredSize() {
      Dimension retDimension = super.getPreferredSize();
      if (retDimension != null) {
        retDimension = new Dimension(retDimension.width + 3,
            retDimension.height);
      }
      return retDimension;
    }
    public void setSelected(boolean isSelected) {
      this.isSelected = isSelected;
    }
    public void setFocus(boolean hasFocus) {
      this.hasFocus = hasFocus;
    }
  }
}
class CheckNode extends DefaultMutableTreeNode {
  public final static int SINGLE_SELECTION = 0;
  public final static int DIG_IN_SELECTION = 4;
  protected int selectionMode;
  protected boolean isSelected;
  public CheckNode() {
    this(null);
  }
  public CheckNode(Object userObject) {
    this(userObject, true, false);
  }
  public CheckNode(Object userObject, boolean allowsChildren,
      boolean isSelected) {
    super(userObject, allowsChildren);
    this.isSelected = isSelected;
    setSelectionMode(DIG_IN_SELECTION);
  }
  public void setSelectionMode(int mode) {
    selectionMode = mode;
  }
  public int getSelectionMode() {
    return selectionMode;
  }
  public void setSelected(boolean isSelected) {
    this.isSelected = isSelected;
    if ((selectionMode == DIG_IN_SELECTION) && (children != null)) {
      Enumeration e = children.elements();
      while (e.hasMoreElements()) {
        CheckNode node = (CheckNode) e.nextElement();
        node.setSelected(isSelected);
      }
    }
  }
  public boolean isSelected() {
    return isSelected;
  }
  // If you want to change "isSelected" by CellEditor,
  /*
   public void setUserObject(Object obj) { if (obj instanceof Boolean) {
   * setSelected(((Boolean)obj).booleanValue()); } else {
   * super.setUserObject(obj); } }
   */
}





Disabled Node Tree Example

// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html
//DisabledNodeTreeExample.java
/* (swing1.1.1beta2) swing#1331 */

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ruponent;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.awt.image.RGBImageFilter;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.border.TitledBorder;
import javax.swing.plaf.metal.MetalLookAndFeel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
/**
 * @version 1.1 04/30/99
 */
public class DisabledNodeTreeExample extends JFrame {
  public DisabledNodeTreeExample() {
    super("DisabledNode TreeExample");
    String[] strs = { "swing", // 0
        "plaf", // 1
        "basic", // 2
        "metal", // 3
        "JTree", // 4
        "plaf", // 5
        "motif" }; // 6
    DisabledNode[] nodes = new DisabledNode[strs.length];
    for (int i = 0; i < strs.length; i++) {
      nodes[i] = new DisabledNode(strs[i]);
    }
    nodes[0].add(nodes[1]);
    nodes[1].add(nodes[2]);
    nodes[1].add(nodes[3]);
    nodes[0].add(nodes[4]);
    nodes[0].add(nodes[5]);
    nodes[5].add(nodes[6]);
    nodes[3].setEnabled(false);
    nodes[5].setEnabled(false);
    final JTree tree = new JTree(nodes[0]) {
      public boolean isPathEditable(TreePath path) {
        DisabledNode node = (DisabledNode) path.getLastPathComponent();
        if (node.isEnabled()) {
          return isEditable();
        } else {
          return false;
        }
      }
    };
    DisabledRenderer renderer = new DisabledRenderer();
    renderer.setDisabledLeafIcon(new DisabledLeafIcon());
    renderer.setDisabledOpenIcon(new DisabledFolderIcon());
    renderer.setDisabledClosedIcon(new DisabledFolderIcon());
    tree.setCellRenderer(renderer);
    tree.setEditable(true);
    JScrollPane sp = new JScrollPane(tree);
    ButtonPanel bp = new ButtonPanel(tree);
    getContentPane().add(sp, BorderLayout.CENTER);
    getContentPane().add(bp, BorderLayout.EAST);
  }
  class ButtonPanel extends JPanel {
    JTree tree;
    DefaultTreeModel model;
    ButtonPanel(JTree tree) {
      this.tree = tree;
      model = (DefaultTreeModel) tree.getModel();
      setLayout(new GridLayout(2, 1));
      setBorder(new TitledBorder("Change Node"));
      JButton enabledButton = new JButton("Enabled");
      JButton disabledButton = new JButton("Disabled");
      add(enabledButton);
      add(disabledButton);
      enabledButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          setNodeEnabled(true);
        }
      });
      disabledButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          setNodeEnabled(false);
        }
      });
    }
    private void setNodeEnabled(boolean enabled) {
      TreePath[] path = tree.getSelectionPaths();
      if (path == null)
        return;
      DisabledNode node = null;
      for (int i = 0; i < path.length; i++) {
        node = (DisabledNode) path[i].getLastPathComponent();
        //if (node.isRoot()) {
        //  System.out.println("refused: root node");
        //} else {
        int beforeChildCount = node.getChildCount();
        node.setEnabled(enabled);
        int afterChildCount = node.getChildCount();
        if (beforeChildCount == afterChildCount) {
          model.nodeChanged(node);
        } else {
          model.reload();
        }
        //}
      }
    }
  }
  public static void main(String args[]) {
    
    try {
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    } catch (Exception evt) {}
    
    DisabledNodeTreeExample frame = new DisabledNodeTreeExample();
    frame.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    frame.setSize(300, 180);
    frame.setVisible(true);
  }
}
class DisabledRenderer extends DefaultTreeCellRenderer {
  protected Icon disabledLeafIcon;
  protected Icon disabledOpenIcon;
  protected Icon disabledClosedIcon;
  public DisabledRenderer() {
    this(new GraydIcon(UIManager.getIcon("Tree.leafIcon")), new GraydIcon(
        UIManager.getIcon("Tree.openIcon")), new GraydIcon(UIManager
        .getIcon("Tree.closedIcon")));
  }
  public DisabledRenderer(Icon leafIcon, Icon openIcon, Icon closedIcon) {
    setDisabledLeafIcon(leafIcon);
    setDisabledOpenIcon(openIcon);
    setDisabledClosedIcon(closedIcon);
  }
  public Component getTreeCellRendererComponent(JTree tree, Object value,
      boolean sel, boolean expanded, boolean leaf, int row,
      boolean hasFocus) {
    String stringValue = tree.convertValueToText(value, sel, expanded,
        leaf, row, hasFocus);
    setText(stringValue);
    if (sel) {
      setForeground(getTextSelectionColor());
    } else {
      setForeground(getTextNonSelectionColor());
    }
    boolean treeIsEnabled = tree.isEnabled();
    boolean nodeIsEnabled = ((DisabledNode) value).isEnabled();
    boolean isEnabled = (treeIsEnabled && nodeIsEnabled);
    setEnabled(isEnabled);
    if (isEnabled) {
      selected = sel;
      if (leaf) {
        setIcon(getLeafIcon());
      } else if (expanded) {
        setIcon(getOpenIcon());
      } else {
        setIcon(getClosedIcon());
      }
    } else {
      selected = false;
      if (leaf) {
        if (nodeIsEnabled) {
          setDisabledIcon(getLeafIcon());
        } else {
          setDisabledIcon(disabledLeafIcon);
        }
      } else if (expanded) {
        if (nodeIsEnabled) {
          setDisabledIcon(getOpenIcon());
        } else {
          setDisabledIcon(disabledOpenIcon);
        }
      } else {
        if (nodeIsEnabled) {
          setDisabledIcon(getClosedIcon());
        } else {
          setDisabledIcon(disabledClosedIcon);
        }
      }
    }
    return this;
  }
  public void setDisabledLeafIcon(Icon icon) {
    disabledLeafIcon = icon;
  }
  public void setDisabledOpenIcon(Icon icon) {
    disabledOpenIcon = icon;
  }
  public void setDisabledClosedIcon(Icon icon) {
    disabledClosedIcon = icon;
  }
}
class DisabledNode extends DefaultMutableTreeNode {
  protected boolean enabled;
  public DisabledNode() {
    this(null, true, true);
  }
  public DisabledNode(Object userObject) {
    this(userObject, true, true);
  }
  public DisabledNode(Object userObject, boolean allowsChildren) {
    this(userObject, allowsChildren, true);
  }
  public DisabledNode(Object userObject, boolean allowsChildren,
      boolean enabled) {
    super(userObject, allowsChildren);
    this.enabled = enabled;
  }
  public int getChildCount() {
    if (enabled) {
      return super.getChildCount();
    } else {
      return 0;
    }
  }
  public boolean isLeaf() {
    return (super.getChildCount() == 0);
  }
  public void setEnabled(boolean enabled) {
    this.enabled = enabled;
  }
  public boolean isEnabled() {
    return enabled;
  }
}
class DisabledLeafIcon implements Icon {
  int width = 16;
  int height = 16;
  int additionalHeight = 4;
  public void paintIcon(Component c, Graphics g, int x, int y) {
    int right = width - 1;
    int bottom = height + 1;
    g.setColor(c.getBackground());
    g.fillRect(0, 0, width, getIconHeight());
    // Draw frame
    g.setColor(MetalLookAndFeel.getControlDisabled());
    g.drawLine(2, 2, 2, bottom); // left
    g.drawLine(2, 2, right - 4, 2); // top
    g.drawLine(2, bottom, right - 1, bottom); // bottom
    g.drawLine(right - 1, 8, right - 1, bottom); // right
    g.drawLine(right - 6, 4, right - 2, 8); // slant 1
    g.drawLine(right - 5, 3, right - 4, 3); // part of slant 2
    g.drawLine(right - 3, 4, right - 3, 5); // part of slant 2
    g.drawLine(right - 2, 6, right - 2, 7); // part of slant 2
  }
  public int getIconWidth() {
    return width;
  }
  public int getIconHeight() {
    return height + additionalHeight;
  }
}
class DisabledFolderIcon implements Icon {
  int width = 16;
  int height = 16;
  int additionalHeight = 2;
  public void paintIcon(Component c, Graphics g, int x, int y) {
    int right = width - 1;
    int bottom = height - 2;
    g.setColor(c.getBackground());
    g.fillRect(0, 0, width, getIconHeight());
    // Draw tab
    g.setColor(MetalLookAndFeel.getControlDisabled());
    g.drawLine(right - 5, 2, right, 2);
    g.drawLine(right - 6, 3, right - 6, 4);
    g.drawLine(right, 3, right, 4);
    // Draw outline
    g.setColor(MetalLookAndFeel.getControlDisabled());
    g.drawLine(0, 5, 0, bottom); // left side
    g.drawLine(1, 4, right - 7, 4); // first part of top
    g.drawLine(right - 6, 5, right - 1, 5); // second part of top
    g.drawLine(right, 4, right, bottom); // right side
    g.drawLine(0, bottom, right, bottom); // bottom
  }
  public int getIconWidth() {
    return width;
  }
  public int getIconHeight() {
    return height + additionalHeight;
  }
}
class GraydIcon implements Icon {
  Icon icon;
  Image image;
  public GraydIcon(Icon icon) {
    this.icon = icon;
  }
  public void paintIcon(Component c, Graphics g, int x, int y) {
    if (image == null) {
      Image orgImage = c.createImage(getIconWidth(), getIconHeight());
      Graphics imageG = orgImage.getGraphics();
      Color background = c.getBackground();
      imageG.setColor(background);
      imageG.fillRect(0, 0, getIconWidth(), getIconHeight());
      icon.paintIcon(c, imageG, x, y);
      ImageFilter colorfilter = new GrayFilter();
      image = c.createImage(new FilteredImageSource(orgImage.getSource(),
          colorfilter));
    }
    g.drawImage(image, x, y, null);
  }
  public int getIconWidth() {
    return icon.getIconWidth();
  }
  public int getIconHeight() {
    return icon.getIconHeight();
  }
  class GrayFilter extends RGBImageFilter {
    public GrayFilter() {
      // If I set ture, black is gone?!
      //canFilterIndexColorModel = true;
    }
    public int filterRGB(int x, int y, int rgb) {
      int r = (rgb & 0xff0000) >> 16;
      int g = (rgb & 0x00ff00) >> 8;
      int b = (rgb & 0x0000ff);
      int iy = (int) (r + g + b) / 3;
      iy = Math.min(255, iy);
      return ((rgb & 0xff000000) | (iy << 16) | (iy << 8) | iy);
    }
  }
}





Disabled Node Tree Example 2

// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html
//DisabledNodeTreeExample2.java
/* (swing1.1.1beta2) swing#1331 */
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ruponent;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.awt.image.RGBImageFilter;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.border.TitledBorder;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
/**
 * @version 1.0 04/30/99
 */
public class DisabledNodeTreeExample2 extends JFrame {
  public DisabledNodeTreeExample2() {
    super("DisabledNode TreeExample");
    String[] strs = { "swing", // 0
        "plaf", // 1
        "basic", // 2
        "metal", // 3
        "JTree", // 4
        "plaf", // 5
        "motif" }; // 6
    DisabledNode[] nodes = new DisabledNode[strs.length];
    for (int i = 0; i < strs.length; i++) {
      nodes[i] = new DisabledNode(strs[i]);
    }
    nodes[0].add(nodes[1]);
    nodes[1].add(nodes[2]);
    nodes[1].add(nodes[3]);
    nodes[0].add(nodes[4]);
    nodes[0].add(nodes[5]);
    nodes[5].add(nodes[6]);
    nodes[3].setEnabled(false);
    nodes[5].setEnabled(false);
    final JTree tree = new JTree(nodes[0]) {
      public boolean isPathEditable(TreePath path) {
        DisabledNode node = (DisabledNode) path.getLastPathComponent();
        if (node.isEnabled()) {
          return isEditable();
        } else {
          return false;
        }
      }
    };
    DisabledRenderer renderer = new DisabledRenderer();
    tree.setCellRenderer(renderer);
    tree.setEditable(true);
    JScrollPane sp = new JScrollPane(tree);
    ButtonPanel bp = new ButtonPanel(tree);
    getContentPane().add(sp, BorderLayout.CENTER);
    getContentPane().add(bp, BorderLayout.EAST);
  }
  class ButtonPanel extends JPanel {
    JTree tree;
    DefaultTreeModel model;
    ButtonPanel(JTree tree) {
      this.tree = tree;
      model = (DefaultTreeModel) tree.getModel();
      setLayout(new GridLayout(2, 1));
      setBorder(new TitledBorder("Change Node"));
      JButton enabledButton = new JButton("Enabled");
      JButton disabledButton = new JButton("Disabled");
      add(enabledButton);
      add(disabledButton);
      enabledButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          setNodeEnabled(true);
        }
      });
      disabledButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          setNodeEnabled(false);
        }
      });
    }
    private void setNodeEnabled(boolean enabled) {
      TreePath[] path = tree.getSelectionPaths();
      if (path == null)
        return;
      DisabledNode node = null;
      for (int i = 0; i < path.length; i++) {
        node = (DisabledNode) path[i].getLastPathComponent();
        //if (node.isRoot()) {
        //  System.out.println("refused: root node");
        //} else {
        int beforeChildCount = node.getChildCount();
        node.setEnabled(enabled);
        int afterChildCount = node.getChildCount();
        if (beforeChildCount == afterChildCount) {
          model.nodeChanged(node);
        } else {
          model.reload();
        }
        //}
      }
    }
  }
  public static void main(String args[]) {
    try {
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    } catch (Exception evt) {}

    DisabledNodeTreeExample2 frame = new DisabledNodeTreeExample2();
    frame.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    frame.setSize(300, 180);
    frame.setVisible(true);
  }
}
class DisabledRenderer extends DefaultTreeCellRenderer {
  protected Icon disabledLeafIcon;
  protected Icon disabledOpenIcon;
  protected Icon disabledClosedIcon;
  public DisabledRenderer() {
    this(new GraydIcon(UIManager.getIcon("Tree.leafIcon")), new GraydIcon(
        UIManager.getIcon("Tree.openIcon")), new GraydIcon(UIManager
        .getIcon("Tree.closedIcon")));
  }
  public DisabledRenderer(Icon leafIcon, Icon openIcon, Icon closedIcon) {
    setDisabledLeafIcon(leafIcon);
    setDisabledOpenIcon(openIcon);
    setDisabledClosedIcon(closedIcon);
  }
  public Component getTreeCellRendererComponent(JTree tree, Object value,
      boolean sel, boolean expanded, boolean leaf, int row,
      boolean hasFocus) {
    String stringValue = tree.convertValueToText(value, sel, expanded,
        leaf, row, hasFocus);
    setText(stringValue);
    if (sel) {
      setForeground(getTextSelectionColor());
    } else {
      setForeground(getTextNonSelectionColor());
    }
    boolean treeIsEnabled = tree.isEnabled();
    boolean nodeIsEnabled = ((DisabledNode) value).isEnabled();
    boolean isEnabled = (treeIsEnabled && nodeIsEnabled);
    setEnabled(isEnabled);
    if (isEnabled) {
      selected = sel;
      if (leaf) {
        setIcon(getLeafIcon());
      } else if (expanded) {
        setIcon(getOpenIcon());
      } else {
        setIcon(getClosedIcon());
      }
    } else {
      selected = false;
      if (leaf) {
        if (nodeIsEnabled) {
          setDisabledIcon(getLeafIcon());
        } else {
          setDisabledIcon(disabledLeafIcon);
        }
      } else if (expanded) {
        if (nodeIsEnabled) {
          setDisabledIcon(getOpenIcon());
        } else {
          setDisabledIcon(disabledOpenIcon);
        }
      } else {
        if (nodeIsEnabled) {
          setDisabledIcon(getClosedIcon());
        } else {
          setDisabledIcon(disabledClosedIcon);
        }
      }
    }
    return this;
  }
  public void setDisabledLeafIcon(Icon icon) {
    disabledLeafIcon = icon;
  }
  public void setDisabledOpenIcon(Icon icon) {
    disabledOpenIcon = icon;
  }
  public void setDisabledClosedIcon(Icon icon) {
    disabledClosedIcon = icon;
  }
}
class DisabledNode extends DefaultMutableTreeNode {
  protected boolean enabled;
  public DisabledNode() {
    this(null, true, true);
  }
  public DisabledNode(Object userObject) {
    this(userObject, true, true);
  }
  public DisabledNode(Object userObject, boolean allowsChildren) {
    this(userObject, allowsChildren, true);
  }
  public DisabledNode(Object userObject, boolean allowsChildren,
      boolean enabled) {
    super(userObject, allowsChildren);
    this.enabled = enabled;
  }
  public int getChildCount() {
    if (enabled) {
      return super.getChildCount();
    } else {
      return 0;
    }
  }
  public boolean isLeaf() {
    return (super.getChildCount() == 0);
  }
  public void setEnabled(boolean enabled) {
    this.enabled = enabled;
  }
  public boolean isEnabled() {
    return enabled;
  }
}
class GraydIcon implements Icon {
  Icon icon;
  Image image;
  public GraydIcon(Icon icon) {
    this.icon = icon;
  }
  public void paintIcon(Component c, Graphics g, int x, int y) {
    if (image == null) {
      Image orgImage = c.createImage(getIconWidth(), getIconHeight());
      Graphics imageG = orgImage.getGraphics();
      Color background = c.getBackground();
      imageG.setColor(background);
      imageG.fillRect(0, 0, getIconWidth(), getIconHeight());
      icon.paintIcon(c, imageG, x, y);
      ImageFilter colorfilter = new GrayFilter();
      image = c.createImage(new FilteredImageSource(orgImage.getSource(),
          colorfilter));
    }
    g.drawImage(image, x, y, null);
  }
  public int getIconWidth() {
    return icon.getIconWidth();
  }
  public int getIconHeight() {
    return icon.getIconHeight();
  }
  class GrayFilter extends RGBImageFilter {
    public GrayFilter() {
      // If I set ture, black is gone?!
      //canFilterIndexColorModel = true;
    }
    public int filterRGB(int x, int y, int rgb) {
      int r = (rgb & 0xff0000) >> 16;
      int g = (rgb & 0x00ff00) >> 8;
      int b = (rgb & 0x0000ff);
      int iy = (int) (r + g + b) / 3;
      iy = Math.min(255, iy);
      return ((rgb & 0xff000000) | (iy << 16) | (iy << 8) | iy);
    }
  }
}





Icon Node Tree Example

// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html
import java.awt.BorderLayout;
import java.awt.ruponent;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Hashtable;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.plaf.metal.MetalIconFactory;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
/**
 * @version 1.0 01/12/99
 */
public class IconNodeTreeExample extends JFrame {
  public IconNodeTreeExample() {
    super("IconNode TreeExample");
    String[] strs = { "swing home", // 0
        "platf", // 1
        "basic.txt", // 2
        "metal.c", // 3
        "metal.java", // 4
        "metal.html", // 5
        "Computer", // 6
        "A:", // 7
        "C:", // 8
        "D:" }; // 9
    IconNode[] nodes = new IconNode[strs.length];
    for (int i = 0; i < strs.length; i++)
      nodes[i] = new IconNode(strs[i]);
    nodes[0].add(nodes[1]);
    for (int i = 2; i <= 5; i++)
      nodes[1].add(nodes[i]);
    nodes[0].add(nodes[6]);
    for (int i = 7; i <= 9; i++)
      nodes[6].add(nodes[i]);
    //
    // set Icon directly
    //
    nodes[0].setIcon(MetalIconFactory.getFileChooserHomeFolderIcon());
    //
    // use JTree default Icon
    //
    // nodes[1]
    // nodes[2]
    //
    // set Icon by user Object
    //
    // nodes[3]
    // nodes[4]
    // nodes[5]
    //
    // set Icon by name
    //
    nodes[6].setIconName("computer");
    nodes[7].setIconName("floppyDrive");
    nodes[8].setIconName("hardDrive");
    nodes[9].setIconName("hardDrive");
    JTree tree = new JTree(nodes[0]);
    tree.putClientProperty("JTree.icons", makeIcons());
    tree.setCellRenderer(new IconNodeRenderer());
    JScrollPane sp = new JScrollPane(tree);
    getContentPane().add(sp, BorderLayout.CENTER);
  }
  private Hashtable makeIcons() {
    Hashtable icons = new Hashtable();
    icons.put("floppyDrive", MetalIconFactory.getTreeFloppyDriveIcon());
    icons.put("hardDrive", MetalIconFactory.getTreeHardDriveIcon());
    icons.put("computer", MetalIconFactory.getTreeComputerIcon());
    icons.put("c", TextIcons.getIcon("c"));
    icons.put("java", TextIcons.getIcon("java"));
    icons.put("html", TextIcons.getIcon("html"));
    return icons;
  }
  public static void main(String args[]) {
    try {
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    } catch (Exception evt) {}
  
    IconNodeTreeExample frame = new IconNodeTreeExample();
    frame.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    frame.setSize(300, 150);
    frame.setVisible(true);
  }
}
class IconNodeRenderer extends DefaultTreeCellRenderer {
  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);
    Icon icon = ((IconNode) value).getIcon();
    if (icon == null) {
      Hashtable icons = (Hashtable) tree.getClientProperty("JTree.icons");
      String name = ((IconNode) value).getIconName();
      if ((icons != null) && (name != null)) {
        icon = (Icon) icons.get(name);
        if (icon != null) {
          setIcon(icon);
        }
      }
    } else {
      setIcon(icon);
    }
    return this;
  }
}
class IconNode extends DefaultMutableTreeNode {
  protected Icon icon;
  protected String iconName;
  public IconNode() {
    this(null);
  }
  public IconNode(Object userObject) {
    this(userObject, true, null);
  }
  public IconNode(Object userObject, boolean allowsChildren, Icon icon) {
    super(userObject, allowsChildren);
    this.icon = icon;
  }
  public void setIcon(Icon icon) {
    this.icon = icon;
  }
  public Icon getIcon() {
    return icon;
  }
  public String getIconName() {
    if (iconName != null) {
      return iconName;
    } else {
      String str = userObject.toString();
      int index = str.lastIndexOf(".");
      if (index != -1) {
        return str.substring(++index);
      } else {
        return null;
      }
    }
  }
  public void setIconName(String name) {
    iconName = name;
  }
}
class TextIcons extends MetalIconFactory.TreeLeafIcon {
  protected String label;
  private static Hashtable labels;
  protected TextIcons() {
  }
  public void paintIcon(Component c, Graphics g, int x, int y) {
    super.paintIcon(c, g, x, y);
    if (label != null) {
      FontMetrics fm = g.getFontMetrics();
      int offsetX = (getIconWidth() - fm.stringWidth(label)) / 2;
      int offsetY = (getIconHeight() - fm.getHeight()) / 2 - 2;
      g.drawString(label, x + offsetX, y + offsetY + fm.getHeight());
    }
  }
  public static Icon getIcon(String str) {
    if (labels == null) {
      labels = new Hashtable();
      setDefaultSet();
    }
    TextIcons icon = new TextIcons();
    icon.label = (String) labels.get(str);
    return icon;
  }
  public static void setLabelSet(String ext, String label) {
    if (labels == null) {
      labels = new Hashtable();
      setDefaultSet();
    }
    labels.put(ext, label);
  }
  private static void setDefaultSet() {
    labels.put("c", "C");
    labels.put("java", "J");
    labels.put("html", "H");
    labels.put("htm", "H");
    // and so on
    /*
     * labels.put("txt" ,"TXT"); labels.put("TXT" ,"TXT"); labels.put("cc"
     * ,"C++"); labels.put("C" ,"C++"); labels.put("cpp" ,"C++");
     * labels.put("exe" ,"BIN"); labels.put("class" ,"BIN");
     * labels.put("gif" ,"GIF"); labels.put("GIF" ,"GIF");
     * 
     * labels.put("", "");
     */
  }
}





Invisible Node Tree Example

// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ruponent;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Enumeration;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.border.TitledBorder;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
/**
 * @version 1.0 01/12/99
 */
public class InvisibleNodeTreeExample extends JFrame {
  public InvisibleNodeTreeExample() {
    super("InvisibleNode TreeExample");
    String[] strs = { "swing", // 0
        "platf", // 1
        "basic", // 2
        "metal", // 3
        "JTree" }; // 4
    InvisibleNode[] nodes = new InvisibleNode[strs.length];
    for (int i = 0; i < strs.length; i++) {
      nodes[i] = new InvisibleNode(strs[i]);
    }
    nodes[0].add(nodes[1]);
    nodes[1].add(nodes[2]);
    nodes[1].add(nodes[3]);
    nodes[0].add(nodes[4]);
    nodes[3].setVisible(false);
    InvisibleTreeModel ml = new InvisibleTreeModel(nodes[0]);
    ml.activateFilter(true);
    JTree tree = new JTree(ml);
    tree.setCellRenderer(new DefaultTreeCellRenderer() {
      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 (!((InvisibleNode) value).isVisible()) {
          setForeground(Color.yellow);
        }
        return this;
      }
    });
    JScrollPane sp = new JScrollPane(tree);
    ModePanel mp = new ModePanel(ml);
    ButtonPanel bp = new ButtonPanel(tree);
    Box box_right = new Box(BoxLayout.Y_AXIS);
    box_right.add(mp);
    box_right.add(bp);
    Box box = new Box(BoxLayout.X_AXIS);
    box.add(sp);
    box.add(Box.createVerticalGlue());
    box.add(box_right);
    getContentPane().add(box, BorderLayout.CENTER);
  }
  class ModePanel extends JPanel {
    ModePanel(final InvisibleTreeModel model) {
      setLayout(new GridLayout(2, 1));
      setBorder(new TitledBorder("View Mode"));
      ButtonGroup group = new ButtonGroup();
      JRadioButton b_all = new JRadioButton("all");
      JRadioButton b_hide = new JRadioButton("hide");
      add(b_all);
      add(b_hide);
      group.add(b_all);
      group.add(b_hide);
      b_all.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          if (model.isActivatedFilter()) {
            model.activateFilter(false);
            model.reload();
          }
        }
      });
      b_hide.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          if (!model.isActivatedFilter()) {
            model.activateFilter(true);
            model.reload();
          }
        }
      });
      b_hide.setSelected(true);
    }
  }
  class ButtonPanel extends JPanel {
    ButtonPanel(final JTree tree) {
      setLayout(new GridLayout(2, 1));
      setBorder(new TitledBorder("Change Node"));
      JButton b_visible = new JButton("Visible");
      JButton b_invisible = new JButton("Invisible");
      //b_invisible.setForeground(Color.yellow);
      add(b_visible);
      add(b_invisible);
      b_visible.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          setNodeVisible(tree, true);
        }
      });
      b_invisible.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          setNodeVisible(tree, false);
        }
      });
    }
    private void setNodeVisible(final JTree tree, boolean isVisible) {
      DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
      TreePath[] path = tree.getSelectionPaths();
      InvisibleNode node = null;
      for (int i = 0; i < path.length; i++) {
        node = (InvisibleNode) path[i].getLastPathComponent();
        if (!(node == model.getRoot())) {
          node.setVisible(isVisible);
        } else {
          System.out.println("refused: root node");
        }
      }
      if (path.length == 1) {
        model.nodeChanged(node);
      } else {
        model.reload();
      }
    }
  }
  public static void main(String args[]) {
    try {
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    } catch (Exception evt) {}
  
    InvisibleNodeTreeExample frame = new InvisibleNodeTreeExample();
    frame.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    frame.setSize(300, 180);
    frame.setVisible(true);
  }
}
class InvisibleTreeModel extends DefaultTreeModel {
  protected boolean filterIsActive;
  public InvisibleTreeModel(TreeNode root) {
    this(root, false);
  }
  public InvisibleTreeModel(TreeNode root, boolean asksAllowsChildren) {
    this(root, false, false);
  }
  public InvisibleTreeModel(TreeNode root, boolean asksAllowsChildren,
      boolean filterIsActive) {
    super(root, asksAllowsChildren);
    this.filterIsActive = filterIsActive;
  }
  public void activateFilter(boolean newValue) {
    filterIsActive = newValue;
  }
  public boolean isActivatedFilter() {
    return filterIsActive;
  }
  public Object getChild(Object parent, int index) {
    if (filterIsActive) {
      if (parent instanceof InvisibleNode) {
        return ((InvisibleNode) parent).getChildAt(index,
            filterIsActive);
      }
    }
    return ((TreeNode) parent).getChildAt(index);
  }
  public int getChildCount(Object parent) {
    if (filterIsActive) {
      if (parent instanceof InvisibleNode) {
        return ((InvisibleNode) parent).getChildCount(filterIsActive);
      }
    }
    return ((TreeNode) parent).getChildCount();
  }
}
class InvisibleNode extends DefaultMutableTreeNode {
  protected boolean isVisible;
  public InvisibleNode() {
    this(null);
  }
  public InvisibleNode(Object userObject) {
    this(userObject, true, true);
  }
  public InvisibleNode(Object userObject, boolean allowsChildren,
      boolean isVisible) {
    super(userObject, allowsChildren);
    this.isVisible = isVisible;
  }
  public TreeNode getChildAt(int index, boolean filterIsActive) {
    if (!filterIsActive) {
      return super.getChildAt(index);
    }
    if (children == null) {
      throw new ArrayIndexOutOfBoundsException("node has no children");
    }
    int realIndex = -1;
    int visibleIndex = -1;
    Enumeration e = children.elements();
    while (e.hasMoreElements()) {
      InvisibleNode node = (InvisibleNode) e.nextElement();
      if (node.isVisible()) {
        visibleIndex++;
      }
      realIndex++;
      if (visibleIndex == index) {
        return (TreeNode) children.elementAt(realIndex);
      }
    }
    throw new ArrayIndexOutOfBoundsException("index unmatched");
    //return (TreeNode)children.elementAt(index);
  }
  public int getChildCount(boolean filterIsActive) {
    if (!filterIsActive) {
      return super.getChildCount();
    }
    if (children == null) {
      return 0;
    }
    int count = 0;
    Enumeration e = children.elements();
    while (e.hasMoreElements()) {
      InvisibleNode node = (InvisibleNode) e.nextElement();
      if (node.isVisible()) {
        count++;
      }
    }
    return count;
  }
  public void setVisible(boolean visible) {
    this.isVisible = visible;
  }
  public boolean isVisible() {
    return isVisible;
  }
}





MultiLine Tree Example

// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html
/* (swing1.1beta3) */

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ruponent;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.ColorUIResource;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeCellRenderer;

/**
 * @version 1.0 11/09/98
 */
public class MultiLineTreeExample extends JFrame {
  public MultiLineTreeExample() {
    super("Multi-Line JTree Example");
    String[] strs = { "swing", // 0
        "package", // 1
        "java.awt.swing\n" + "com.sun.java.swing", // 2
        "javax.swing", // 3
        "JTree" }; // 4
    DefaultMutableTreeNode[] nodes = new DefaultMutableTreeNode[strs.length];
    for (int i = 0; i < strs.length; i++) {
      nodes[i] = new DefaultMutableTreeNode(strs[i]);
    }
    nodes[0].add(nodes[1]);
    nodes[1].add(nodes[2]);
    nodes[1].add(nodes[3]);
    nodes[0].add(nodes[4]);
    JTree tree = new JTree(nodes[0]);
    tree.setCellRenderer(new MultiLineCellRenderer());
    JScrollPane sp = new JScrollPane();
    sp.getViewport().add(tree);
    getContentPane().add(sp, BorderLayout.CENTER);
  }
  public static void main(String args[]) {
    try {
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    } catch (Exception evt) {}
    MultiLineTreeExample frame = new MultiLineTreeExample();
    frame.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    frame.setSize(300, 150);
    frame.setVisible(true);
  }
}
class MultiLineCellRenderer extends JPanel implements TreeCellRenderer {
  protected JLabel icon;
  protected TreeTextArea text;
  public MultiLineCellRenderer() {
    setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
    icon = new JLabel() {
      public void setBackground(Color color) {
        if (color instanceof ColorUIResource)
          color = null;
        super.setBackground(color);
      }
    };
    add(icon);
    add(Box.createHorizontalStrut(4));
    add(text = new TreeTextArea());
  }
  public Component getTreeCellRendererComponent(JTree tree, Object value,
      boolean isSelected, boolean expanded, boolean leaf, int row,
      boolean hasFocus) {
    String stringValue = tree.convertValueToText(value, isSelected,
        expanded, leaf, row, hasFocus);
    setEnabled(tree.isEnabled());
    text.setText(stringValue);
    text.setSelect(isSelected);
    text.setFocus(hasFocus);
    if (leaf) {
      icon.setIcon(UIManager.getIcon("Tree.leafIcon"));
    } else if (expanded) {
      icon.setIcon(UIManager.getIcon("Tree.openIcon"));
    } else {
      icon.setIcon(UIManager.getIcon("Tree.closedIcon"));
    }
    return this;
  }
  public Dimension getPreferredSize() {
    Dimension iconD = icon.getPreferredSize();
    Dimension textD = text.getPreferredSize();
    int height = iconD.height < textD.height ? textD.height : iconD.height;
    return new Dimension(iconD.width + textD.width, height);
  }
  public void setBackground(Color color) {
    if (color instanceof ColorUIResource)
      color = null;
    super.setBackground(color);
  }
  class TreeTextArea extends JTextArea {
    Dimension preferredSize;
    TreeTextArea() {
      setLineWrap(true);
      setWrapStyleWord(true);
      setOpaque(true);
    }
    public void setBackground(Color color) {
      if (color instanceof ColorUIResource)
        color = null;
      super.setBackground(color);
    }
    public void setPreferredSize(Dimension d) {
      if (d != null) {
        preferredSize = d;
      }
    }
    public Dimension getPreferredSize() {
      return preferredSize;
    }
    public void setText(String str) {
      FontMetrics fm = getToolkit().getFontMetrics(getFont());
      BufferedReader br = new BufferedReader(new StringReader(str));
      String line;
      int maxWidth = 0, lines = 0;
      try {
        while ((line = br.readLine()) != null) {
          int width = SwingUtilities.ruputeStringWidth(fm, line);
          if (maxWidth < width) {
            maxWidth = width;
          }
          lines++;
        }
      } catch (IOException ex) {
        ex.printStackTrace();
      }
      lines = (lines < 1) ? 1 : lines;
      int height = fm.getHeight() * lines;
      setPreferredSize(new Dimension(maxWidth + 6, height));
      super.setText(str);
    }
    void setSelect(boolean isSelected) {
      Color bColor;
      if (isSelected) {
        bColor = UIManager.getColor("Tree.selectionBackground");
      } else {
        bColor = UIManager.getColor("Tree.textBackground");
      }
      super.setBackground(bColor);
    }
    void setFocus(boolean hasFocus) {
      if (hasFocus) {
        Color lineColor = UIManager
            .getColor("Tree.selectionBorderColor");
        setBorder(BorderFactory.createLineBorder(lineColor));
      } else {
        setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
      }
    }
  }
}





Only Text Tree Example

// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html
/* (swing1.1.1beta2) */

import java.awt.BorderLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.plaf.basic.BasicTreeUI;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
/**
 * @version 1.0 04/16/99
 */
public class OnlyTextTreeExample extends JFrame {
  public OnlyTextTreeExample() {
    super("OnlyTextTreeExample");
    String[] strs = { "swing", // 0
        "platf", // 1
        "basic", // 2
        "metal", // 3
        "JTree" }; // 4
    DefaultMutableTreeNode[] nodes = new DefaultMutableTreeNode[strs.length];
    for (int i = 0; i < strs.length; i++) {
      nodes[i] = new DefaultMutableTreeNode(strs[i]);
    }
    nodes[0].add(nodes[1]);
    nodes[1].add(nodes[2]);
    nodes[1].add(nodes[3]);
    nodes[0].add(nodes[4]);
    JTree tree = new JTree(nodes[0]);
    DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) tree
        .getCellRenderer();
    renderer.setOpenIcon(null);
    renderer.setClosedIcon(null);
    renderer.setLeafIcon(null);
    BasicTreeUI ui = (BasicTreeUI) tree.getUI();
    ui.setExpandedIcon(null);
    ui.setCollapsedIcon(null);
    JScrollPane sp = new JScrollPane(tree);
    getContentPane().add(sp, BorderLayout.CENTER);
  }
  public static void main(String args[]) {
    try {
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    } catch (Exception evt) {}
  
    OnlyTextTreeExample frame = new OnlyTextTreeExample();
    frame.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    frame.setSize(300, 150);
    frame.setVisible(true);
  }
}





Source code for building a tree in Swing

ToolTip Tree Example

// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html
import java.awt.BorderLayout;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
/**
 * @version 1.0 11/09/98
 */
class ToolTipTreeNode extends DefaultMutableTreeNode {
  private String toolTipText;
  public ToolTipTreeNode(String str, String toolTipText) {
    super(str);
    this.toolTipText = toolTipText;
  }
  public String getToolTipText() {
    return toolTipText;
  }
}
public class ToolTipTreeExample extends JFrame {
  public ToolTipTreeExample() {
    super("ToolTipTreeExample");
    String[][] strs = { { "swing", "boat" }, // 0
        { "platf", "paltform" }, // 1
        { "basic", "fortran" }, // 2
        { "metal", "heavy" }, // 3
        { "JTree", "three" } }; // 4
    ToolTipTreeNode[] nodes = new ToolTipTreeNode[strs.length];
    for (int i = 0; i < strs.length; i++) {
      nodes[i] = new ToolTipTreeNode(strs[i][0], strs[i][1]);
    }
    nodes[0].add(nodes[1]);
    nodes[1].add(nodes[2]);
    nodes[1].add(nodes[3]);
    nodes[0].add(nodes[4]);
    JTree tree = new JTree(nodes[0]) {
      public String getToolTipText(MouseEvent evt) {
        if (getRowForLocation(evt.getX(), evt.getY()) == -1)
          return null;
        TreePath curPath = getPathForLocation(evt.getX(), evt.getY());
        return ((ToolTipTreeNode) curPath.getLastPathComponent())
            .getToolTipText();
      }
    };
    tree.setToolTipText("");
    JScrollPane sp = new JScrollPane(tree);
    getContentPane().add(sp, BorderLayout.CENTER);
  }
  public static void main(String args[]) {
    try {
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    } catch (Exception evt) {}
  
    ToolTipTreeExample frame = new ToolTipTreeExample();
    frame.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    frame.setSize(300, 150);
    frame.setVisible(true);
  }
}





Wide Editor Tree Example

// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html
/*  
 * 
 * This example works only each Icon has same width.
 *
 * editing JTextField has minimum 100. (swing1.1beta3) swing#1007
 *
 */
import java.awt.BorderLayout;
import java.awt.ruponent;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellEditor;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreePath;
//

/**
 * @version 1.0 11/09/98
 */
public class WideEditorTreeExample extends JFrame {
  public WideEditorTreeExample() {
    super("Wide Editor JTree Example");
    String[] strs = { "swing", // 0
        "plaf", // 1
        "basic", // 2
        "metal", // 3
        "JTree" }; // 4
    DefaultMutableTreeNode[] nodes = new DefaultMutableTreeNode[strs.length];
    for (int i = 0; i < strs.length; i++)
      nodes[i] = new DefaultMutableTreeNode(strs[i]);
    nodes[0].add(nodes[1]);
    nodes[1].add(nodes[2]);
    nodes[1].add(nodes[3]);
    nodes[0].add(nodes[4]);
    JTree tree = new JTree(nodes[0]);
    tree.setEditable(true);
    /*
     * swing1.0.3 tree.setCellEditor(new BasicTreeCellEditor(
     * (BasicTreeCellRenderer)tree.getCellRenderer()) { public void
     * doLayout() { if (editor != null) { Dimension cSize = getSize();
     * Dimension eSize = editor.getPreferredSize(); int n =
     * lastPath.getPathCount(); Rectangle r = new Rectangle(); r =
     * changeTree.getBounds(r); eSize.width = r.width -(editingOffset *n);
     * editor.setSize(eSize); editor.setLocation(editingOffset, 0);
     * editor.setBounds(editingOffset, 0, eSize.width, cSize.height);
     * setSize(new Dimension(eSize.width + editingOffset, cSize.height)); } } } );
     */
    // swing1.1beta3
    tree.setCellEditor(new WideCellEditor(tree,
        (DefaultTreeCellRenderer) tree.getCellRenderer()));
    //
    JScrollPane sp = new JScrollPane(tree);
    getContentPane().add(sp, BorderLayout.CENTER);
  }
  public static void main(String args[]) {
    try {
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    } catch (Exception evt) {}
  
    WideEditorTreeExample frame = new WideEditorTreeExample();
    frame.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    frame.setSize(300, 150);
    frame.setVisible(true);
  }
}
class WideCellEditor extends DefaultTreeCellEditor {
  public WideCellEditor(JTree tree, DefaultTreeCellRenderer renderer) {
    this(tree, renderer, null);
  }
  public WideCellEditor(final JTree tree,
      final DefaultTreeCellRenderer renderer, TreeCellEditor editor) {
    super(tree, renderer, editor);
    editingContainer = new WideEditorContainer();
  }
  public Component getTreeCellEditorComponent(JTree tree, Object value,
      boolean isSelected, boolean expanded, boolean leaf, int row) {
    Component c = super.getTreeCellEditorComponent(tree, value, isSelected,
        expanded, leaf, row);
    ((WideEditorContainer) editingContainer).setLocalCopy(tree, lastPath,
        offset, editingComponent);
    return c;
  }
  class WideEditorContainer extends DefaultTreeCellEditor.EditorContainer {
    JTree tree;
    TreePath lastPath;
    int offset;
    Component editingComponent;
    public void doLayout() {
      if (editingComponent != null) {
        Dimension cSize = getSize();
        Dimension eSize = editingComponent.getPreferredSize();
        int n = lastPath.getPathCount();
        Rectangle r = new Rectangle();
        r = tree.getBounds(r);
        eSize.width = r.width - (offset * n);
        editingComponent.setSize(eSize);
        editingComponent.setLocation(offset, 0);
        editingComponent
            .setBounds(offset, 0, eSize.width, cSize.height);
        setSize(new Dimension(eSize.width + offset, cSize.height));
      }
    }
    void setLocalCopy(JTree tree, TreePath lastPath, int offset,
        Component editingComponent) {
      this.tree = tree;
      this.lastPath = lastPath;
      this.offset = offset;
      this.editingComponent = editingComponent;
    }
  }
}