import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.Vector;
import javax.swing.AbstractCellEditor;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;
public class CheckableTree extends JFrame {
private JTree tree;
private ButtonGroup group = new ButtonGroup();
public CheckableTree() {
initComponents();
}
private void initComponents() {
this.setSize(new Dimension(480, 512));
this.setLayout(new BorderLayout());
Node colorNodes[] = {
new Node("blue", false, false),
new Node("violet", false, false),
new Node("red", false, false),
new Node("yellow", false, false)
};
NamedVector parentNode = new NamedVector("colors", colorNodes);
NamedVector rootNode = new NamedVector("root", new Object[] {parentNode});
tree = new JTree(rootNode);
tree.setRootVisible(false);
tree.setEditable(true);
tree.setCellRenderer(new NodeRenderer(group));
tree.setCellEditor(new CheckTreeEditor(group));
tree.setEditable(true);
this.add(tree);
}
public static void main(String[] args) {
CheckableTree frame = new CheckableTree();
frame.setVisible(true);
}
class Node extends DefaultMutableTreeNode {
String text;
boolean isCheckBoxChecked = false;
boolean isRadioButtonChecked = false;
public Node(String text, boolean isCheckBoxChecked, boolean isRadioButtonChecked) {
this.text = text;
this.isCheckBoxChecked = isCheckBoxChecked;
this.isRadioButtonChecked = isRadioButtonChecked;
}
}
class RendererComponent extends JPanel {
JCheckBox checkBox = new JCheckBox();
JRadioButton radioButton = new JRadioButton();
JLabel label = new JLabel();
public RendererComponent() {
setLayout(new FlowLayout(0, 0, FlowLayout.LEFT));
add(radioButton);
add(checkBox);
add(label);
}
}
class NodeRenderer implements TreeCellRenderer {
DefaultTreeCellRenderer defaultRenderer = new DefaultTreeCellRenderer();
RendererComponent renderer = new RendererComponent();
ButtonGroup group;
public NodeRenderer(ButtonGroup group) {
this.group = group;
this.group.add(renderer.radioButton);
Boolean drawFocusBorder = (Boolean) UIManager.get("Tree.drawsFocusBorderAroundIcon");
renderer.checkBox.setFocusPainted((drawFocusBorder != null) && drawFocusBorder.booleanValue());
renderer.radioButton.setFocusPainted((drawFocusBorder != null) && drawFocusBorder.booleanValue());
}
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
Component treeRenderer;
if (leaf) {
String text = tree.convertValueToText(value, selected, expanded, leaf, row, false);
renderer.label.setText(text);
renderer.checkBox.setSelected(false);
renderer.radioButton.setSelected(false);
renderer.setEnabled(tree.isEnabled());
if (selected) {
renderer.setForeground(UIManager.getColor("Tree.selectionForeground"));
renderer.setBackground(UIManager.getColor("Tree.selectionBackground"));
} else {
renderer.setForeground(UIManager.getColor("Tree.textForeground"));
renderer.setBackground(UIManager.getColor("Tree.textBackground"));
}
if ((value != null) && (value instanceof DefaultMutableTreeNode)) {
Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
if (userObject instanceof Node) {
Node node = (Node) userObject;
renderer.label.setText(node.text);
renderer.checkBox.setSelected(node.isCheckBoxChecked);
renderer.radioButton.setSelected(node.isRadioButtonChecked);
}
}
treeRenderer = renderer;
} else {
treeRenderer = defaultRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
}
return treeRenderer;
}
}
class CheckTreeEditor extends AbstractCellEditor implements TreeCellEditor {
private final NodeRenderer renderer;
public CheckTreeEditor(ButtonGroup group) {
renderer = new NodeRenderer(group);
}
@Override
public Object getCellEditorValue() {
JCheckBox checkBox = renderer.renderer.checkBox;
JRadioButton radioButton = renderer.renderer.radioButton;
JLabel label = renderer.renderer.label;
Node node = new Node(label.getText(), checkBox.isSelected(), radioButton.isSelected());
return node;
}
@Override
public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) {
Component editor = renderer.getTreeCellRendererComponent(tree, value, true, expanded, leaf, row, true);
return editor;
}
}
class NamedVector extends Vector {
String name;
public NamedVector(String name, Object elements[]) {
this.name = name;
for (int i = 0, n = elements.length; i < n; i++) {
add(elements[i]);
}
}
@Override
public String toString() {
return name;
}
}
}