Java/Swing Components/Tree
Содержание
- 1 Animated Icon Tree Example
- 2 Animated Icon Tree Example 2
- 3 Checkbox Node Tree Example
- 4 Disabled Node Tree Example
- 5 Disabled Node Tree Example 2
- 6 Icon Node Tree Example
- 7 Invisible Node Tree Example
- 8 MultiLine Tree Example
- 9 Only Text Tree Example
- 10 Source code for building a tree in Swing
- 11 ToolTip Tree Example
- 12 Wide Editor Tree Example
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;
}
}
}