CheckBox Tree 是常見 UI 元件,本文實現經典遞歸選取規則:父節點勾選 → 所有子孫全選;父節點取消 → 所有子孫全取消。
public class CheckBoxTreeNode extends DefaultMutableTreeNode {
private boolean checked = false;
public CheckBoxTreeNode(Object userObject) { super(userObject); }
public boolean isChecked() { return checked; }
public void setChecked(boolean checked) { this.checked = checked; }
}
public class CheckBoxTreeCellRenderer extends JCheckBox implements TreeCellRenderer {
public CheckBoxTreeCellRenderer() { setOpaque(false); }
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
CheckBoxTreeNode node = (CheckBoxTreeNode) value;
setText(node.toString());
if (node.isChecked()) {
setSelected(true);
setForeground(Color.BLUE);
} else {
setSelected(false);
setForeground(tree.getForeground());
}
return this;
}
}
public class CheckBoxTree extends JTree {
public CheckBoxTree(TreeModel model) {
super(model);
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
int row = getRowForLocation(e.getX(), e.getY());
TreePath path = getPathForRow(row);
if (path == null) return;
CheckBoxTreeNode node = (CheckBoxTreeNode) path.getLastPathComponent();
boolean newState = !node.isChecked(); // 切換狀態
checkNode(node, newState); // 遞歸更新
repaint(); // 觸發重繪
}
private void checkNode(CheckBoxTreeNode node, boolean checking) {
node.setChecked(checking);
if (!node.isLeaf()) {
Enumeration<CheckBoxTreeNode> children = node.children();
while (children.hasMoreElements()) {
checkNode(children.nextElement(), checking);
}
}
}
});
}
}
checked 狀態,渲染器唯讀反映此實現適用於權限樹、目錄結構、分類管理等場景。生產環境建議使用成熟元件庫 (如 JIDE、SwingX) 以獲得更完整的無障礙與效能優化。