//有点小BUG未解决package cn.anhong.tools;
import java.awt.BorderLayout;import java.awt.Color;import java.awt.Component;import java.awt.Font;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.ItemEvent;import java.awt.event.ItemListener;import java.awt.event.MouseEvent;import java.util.Arrays;import java.util.EventObject;import java.util.Vector;
import javax.swing.AbstractCellEditor;import javax.swing.JButton;import javax.swing.JCheckBox;import javax.swing.JFrame;import javax.swing.JOptionPane;import javax.swing.JScrollPane;import javax.swing.JTextArea;import javax.swing.JTree;import javax.swing.UIManager;import javax.swing.event.ChangeEvent;import javax.swing.tree.DefaultMutableTreeNode;import javax.swing.tree.DefaultTreeCellRenderer;import javax.swing.tree.TreeCellEditor;import javax.swing.tree.TreeCellRenderer;import javax.swing.tree.TreeNode;import javax.swing.tree.TreePath;
/** * * @author anhong */public class CheckBoxNodeTreeSample {
public static void main(String args[]) { final JFrame frame = new JFrame("CheckBox Tree"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
CheckBoxNode accessibilityOptions[] = { new CheckBoxNode( "Move system caret with focus/selection changes", false), new CheckBoxNode("Always expand alt text for images", true)}; CheckBoxNode browsingOptions[] = { new CheckBoxNode("Notify when downloads complete", true), new CheckBoxNode("Disable script debugging", true), new CheckBoxNode("Use AutoComplete", true), new CheckBoxNode("Browse in a new process", false)}; Vector accessVector = new NamedVector("Accessibility", accessibilityOptions); Vector browseVector = new NamedVector("Browsing", browsingOptions); Object rootNodes[] = {accessVector, browseVector}; Vector rootVector = new NamedVector("Root", rootNodes); final JTree tree = new JTree(rootVector);
CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer(); tree.setCellRenderer(renderer);
tree.setCellEditor(new CheckBoxNodeEditor(tree)); tree.setEditable(true); for (int i = 0; i < tree.getRowCount(); i++) { tree.expandRow(i); }
JScrollPane scrollPane = new JScrollPane(tree); frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
JButton button = new JButton("测试"); button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { TreeNode root = (TreeNode) tree.getModel().getRoot(); StringBuilder buffer = new StringBuilder(); buffer.append("---/r/n"); for (int i = 0; i < root.getChildCount(); i++) { DefaultMutableTreeNode parent = (DefaultMutableTreeNode) root.getChildAt(i); NamedVector vt = (NamedVector) parent.getUserObject(); buffer.append(vt.toText()); buffer.append("/r/n"); } buffer.append("---"); JTextArea area = new JTextArea(5, 30); area.setText(buffer.toString()); JScrollPane panel = new JScrollPane(area); JOptionPane.showMessageDialog(frame, panel); } }); frame.getContentPane().add(button, BorderLayout.SOUTH);
frame.setSize(600, 450); frame.setLocationRelativeTo(null); frame.setVisible(true); }}
class CheckBoxNodeRenderer implements TreeCellRenderer {
private JCheckBox leafRenderer = new JCheckBox(); private DefaultTreeCellRenderer nonLeafRenderer = new DefaultTreeCellRenderer(); Color selectionBorderColor, selectionForeground, selectionBackground, textForeground, textBackground;
protected JCheckBox getLeafRenderer() { return leafRenderer; }
public CheckBoxNodeRenderer() { Font fontValue; fontValue = UIManager.getFont("Tree.font"); if (fontValue != null) { leafRenderer.setFont(fontValue); } Boolean booleanValue = (Boolean) UIManager.get("Tree.drawsFocusBorderAroundIcon"); leafRenderer.setFocusPainted((booleanValue != null) && (booleanValue.booleanValue()));
selectionBorderColor = UIManager.getColor("Tree.selectionBorderColor"); selectionForeground = UIManager.getColor("Tree.selectionForeground"); selectionBackground = UIManager.getColor("Tree.selectionBackground"); textForeground = UIManager.getColor("Tree.textForeground"); textBackground = UIManager.getColor("Tree.textBackground"); }
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
Component returnValue; if (leaf) {
String stringValue = tree.convertValueToText(value, selected, expanded, leaf, row, false); leafRenderer.setText(stringValue); leafRenderer.setSelected(false);
leafRenderer.setEnabled(tree.isEnabled());
if (selected) { leafRenderer.setForeground(selectionForeground); leafRenderer.setBackground(selectionBackground); } else { leafRenderer.setForeground(textForeground); leafRenderer.setBackground(textBackground); }
if ((value != null) && (value instanceof DefaultMutableTreeNode)) { Object userObject = ((DefaultMutableTreeNode) value).getUserObject(); if (userObject instanceof CheckBoxNode) { CheckBoxNode node = (CheckBoxNode) userObject; leafRenderer.setText(node.getText()); leafRenderer.setSelected(node.isSelected()); } } returnValue = leafRenderer; } else { returnValue = nonLeafRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); } return returnValue; }}
class CheckBoxNodeEditor extends AbstractCellEditor implements TreeCellEditor {
CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer(); ChangeEvent changeEvent = null; JTree tree;
public CheckBoxNodeEditor(JTree tree) { this.tree = tree; }
public Object getCellEditorValue() { JCheckBox checkbox = renderer.getLeafRenderer(); CheckBoxNode checkBoxNode = new CheckBoxNode(checkbox.getText(), checkbox.isSelected()); return checkBoxNode; }
public boolean isCellEditable(EventObject event) { boolean returnValue = false; if (event instanceof MouseEvent) { MouseEvent mouseEvent = (MouseEvent) event; TreePath path = tree.getPathForLocation(mouseEvent.getX(), mouseEvent.getY()); if (path != null) { Object node = path.getLastPathComponent(); if ((node != null) && (node instanceof DefaultMutableTreeNode)) { DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) node; Object userObject = treeNode.getUserObject(); returnValue = ((treeNode.isLeaf()) && (userObject instanceof CheckBoxNode)); } } } return returnValue; }
public Component getTreeCellEditorComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row) {
Component editor = renderer.getTreeCellRendererComponent(tree, value, true, expanded, leaf, row, true);
// editor always selected / focused ItemListener itemListener = new ItemListener() {
public void itemStateChanged(ItemEvent itemEvent) { if (stopCellEditing()) { fireEditingStopped(); } } }; if (editor instanceof JCheckBox) { JCheckBox box = (JCheckBox) editor; box.addItemListener(itemListener); }
return editor; }}
class CheckBoxNode {
String text; boolean selected;
public CheckBoxNode(String text, boolean selected) { this.text = text; this.selected = selected; }
public boolean isSelected() { return selected; }
public void setSelected(boolean newValue) { selected = newValue; }
public String getText() { return text; }
public void setText(String newValue) { text = newValue; }
public String toString() { return "<" + text + "(" + selected + ")>"; }}
class NamedVector extends Vector {
String name;
public NamedVector(String name) { this.name = name; }
public NamedVector(String name, Object elements[]) { this.name = name; for (int i = 0, n = elements.length; i < n; i++) { add(elements[i]); } }
public String toString() { return "[" + name + "]"; }
public String toText() { return "[" + name + "]" + Arrays.toString(this.toArray()); }}
