首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java Swing 實現三狀態聯動 CheckBox Tree (父子節點遞歸選取)

     編輯:Java 相關知識

CheckBox Tree 是常見 UI 元件,本文實現經典遞歸選取規則:父節點勾選 → 所有子孫全選;父節點取消 → 所有子孫全取消。

核心類別設計

1. 擴充節點模型

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; }
}

2. 自訂渲染器

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;
    }
}

3. 滑鼠事件處理與遞歸邏輯

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);
                    }
                }
            }
        });
    }
}

關鍵設計模式

  1. 模型驅動視圖:節點模型持有 checked 狀態,渲染器唯讀反映
  2. 事件 → 模型更新 → repaint() → 渲染器讀取:標準 MVC 流程
  3. 遞歸演算法:深度優先遍歷子樹,O(n) 時間複雜度

擴充建議

  • 加入「半選」狀態 (Indeterminate) 支援部分子節點選取
  • 鍵盤無障礙支援 (Space 切換、方向鍵導航)
  • 延遲載入大量節點 (Lazy Loading)
  • 整合 TreeSelectionListener 同步選取與勾選狀態

此實現適用於權限樹、目錄結構、分類管理等場景。生產環境建議使用成熟元件庫 (如 JIDE、SwingX) 以獲得更完整的無障礙與效能優化。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved