分类:
2010-01-25 21:50:50
* @version 1.0 12/06/2006
* @author Thatboy
*/
public class MyTreeWithCheckbox {
//用一个HashMap来保存每个节点的选择状态
private HashMap
public MyTreeWithCheckbox(JTree jTree) {
DefaultMutableTreeNode root = (DefaultMutableTreeNode) jTree.getModel().getRoot();
for (Enumeration em = root.depthFirstEnumeration(); em.hasMoreElements(); ) {
hm.put((DefaultMutableTreeNode) em.nextElement(), TristateCheckBox.NOT_SELECTED);
}
jTree.setCellRenderer(new MyTreeWithCheckboxRenderer());
jTree.addTreeSelectionListener(new MyTreeWithCheckboxSelectionListener());
}
/** 返回所有选中的路径 */
public TreePath[] getSelectionPaths() {
Iterator it = hm.keySet().iterator();
ArrayList
while (it.hasNext()) {
DefaultMutableTreeNode o = (DefaultMutableTreeNode) it.next();
if (o.isLeaf() && ((TristateCheckBox.State) hm.get(o)).equals(TristateCheckBox.SELECTED)) {
al.add(new TreePath(o.getPath()));
}
}
return (TreePath[]) al.toArray(new TreePath[0]);
}
class MyTreeWithCheckboxSelectionListener implements TreeSelectionListener {
public void valueChanged(TreeSelectionEvent e) {
JTree jTree = (JTree) (e.getSource());
DefaultMutableTreeNode node = (DefaultMutableTreeNode) jTree.getLastSelectedPathComponent();
if (node == null) {
return;
}
// 修改当前节点的状态
if (((TristateCheckBox.State) hm.get(node)).equals(TristateCheckBox.SELECTED)) {
hm.put(node, TristateCheckBox.NOT_SELECTED);
} else {
hm.put(node, TristateCheckBox.SELECTED);
}
updateAllParentNodes(node);
updateAllChildNodes(node);
jTree.setSelectionPath(null);
jTree.repaint();
}
/** 用递归方法修改从当前节点到根节点的所有节点的状态*/
public void updateAllParentNodes(DefaultMutableTreeNode node) {
TristateCheckBox.State status = (TristateCheckBox.State) hm.get(node);
if (node.isRoot()) {
return;
}
hm.put(node.getParent(), status);
for (Enumeration em = node.getParent().children(); em.hasMoreElements(); ) {
DefaultMutableTreeNode tn = (DefaultMutableTreeNode) em.nextElement();
if (!((TristateCheckBox.State) hm.get(tn)).equals(status)) {
hm.put(node.getParent(), TristateCheckBox.DONT_CARE);
break;
}
}
updateAllParentNodes((DefaultMutableTreeNode) node.getParent());
}
/** 用递归方法修改以当前节点为根的子树的所有节点的状态*/
public void updateAllChildNodes(DefaultMutableTreeNode node) {
TristateCheckBox.State status = (TristateCheckBox.State) hm.get(node);
for (Enumeration em = node.depthFirstEnumeration(); em.hasMoreElements(); ) {
DefaultMutableTreeNode tn = (DefaultMutableTreeNode) em.nextElement();
hm.put(tn, status);
}
}
}
class MyTreeWithCheckboxRenderer extends DefaultTreeCellRenderer {
private static final long serialVersionUID = 1L;
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected,
boolean expanded, boolean leaf, int row, boolean hasFocus) {
TristateCheckBox checkBox = new TristateCheckBox(value.toString());
checkBox.setOpaque(false);
DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
checkBox.setState(((TristateCheckBox.State) hm.get(node)));
return checkBox;
}
}
}
//顺便写个测试代码吧 TreeDemo.java
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import java.awt.BorderLayout;
public class TreeDemo extends JPanel {
private JTree tree;
public TreeDemo() {
this.setLayout(new BorderLayout());
tree = new JTree();
//用MyTreeWithCheckbox来实现用JCheckbox做节点的JTree
new MyTreeWithCheckbox(tree);
JScrollPane treeView = new JScrollPane(tree);
treeView.setPreferredSize(new Dimension(500, 400));
add(treeView);
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("TreeDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TreeDemo newContentPane = new TreeDemo();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}