<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    John Jiang

    a cup of Java, cheers!
    https://github.com/johnshajiang/blog

       :: 首頁 ::  :: 聯系 :: 聚合  :: 管理 ::
      131 隨筆 :: 1 文章 :: 530 評論 :: 0 Trackbacks
    一個簡單的CheckBox Tree實現
    CheckBox Tree是一個十分常用的UI組件,它能使用戶方便地按特定規則勾選樹中的節點。本文實現了一種簡單的Checking規則:當勾選了某節點后,該節點的所有下級節點全部被勾選;當取消勾選某節點后,該節點的所有下級節點全部被取消勾選。(2009.08.05最后更新)

    實現CheckBox Tree的常用方法,就是使用JCheckBox作為JTree的TreeCellRendrer,并且需要實現特定的Checking規則來勾選/取消勾選CheckBox。

    1. 樹節點
    DefaultMutableTreeNode是最常用的TreeNode實現,此處我們將擴展這一實現--CheckBoxTreeNode,增加一個屬性isChecked,用于標識該節點是否要被勾選上。該類的完整代碼如下所示:
    public class CheckBoxTreeNode extends DefaultMutableTreeNode {

           
    private static final long serialVersionUID = 3195314943599939279L;

           
    private boolean isChecked = false;

           
    public CheckBoxTreeNode(Object userObject) {
                   
    super(userObject);
           }

           
    public boolean isChecked() {
                   
    return isChecked;
           }

           
    public void setChecked(boolean isChecked) {
                   
    this.isChecked = isChecked;
           }
    }

    2. 渲染器
    如本文開頭所述,我們將使用JCheckBox作為樹節點展現形式的渲染器,同時確定對節點進行勾選或取消勾選的規則。CheckBoxTreeCellRenderer本身即是一個JCheckBox,那么在實現getTreeCellRendererComponent方法時,只簡單地返回它自己的實例即可,而對于勾選或取消勾選的條件,則由CheckBoxTreeNode中的isChecked屬性來確定,完整的代碼如下所示:
    public class CheckBoxTreeCellRenderer extends JCheckBox implements TreeCellRenderer {

           
    private static final long serialVersionUID = -6432020851855339311L;

           
    public CheckBoxTreeCellRenderer() {
                   setOpaque(
    false);
           }

           
    public Component getTreeCellRendererComponent(JTree tree, Object value,
                           
    boolean selected, boolean expanded, boolean leaf, int row,
                           
    boolean hasFocus) {
                   CheckBoxTreeNode node 
    = ((CheckBoxTreeNode) value); // 獲取樹節點對象。
                   setText(node.toString()); // 設置CheckBox所展示的文本。

                   
    // 當樹節點被設置為勾選時,則該節點對應的CheckBox被勾選上;否則,取消勾選。
                   if (node.isChecked()) {
                           setSelected(
    true);
                           setForeground(Color.BLUE);
                   } 
    else {
                           setSelected(
    false);
                           setForeground(tree.getForeground());
                   }
                   
    return this;
           }
    }

    3. 樹
    此處對JTree進行擴展,創建CheckBoxTree,該類只是為JTree添加了一個MouseListener,以偵聽鼠標選中樹節點后,如何設置勾選標記,并重繪樹。
    public class CheckBoxTree extends JTree {

           
    private static final long serialVersionUID = -217950037507321241L;

           
    public CheckBoxTree(TreeModel newModel) {
                   
    super(newModel);
                   addCheckingListener();
           }

           
    private void addCheckingListener() {
                   addMouseListener(
    new MouseAdapter() {

                           @Override
                           
    public void mousePressed(MouseEvent e) {
                                   
    int row = getRowForLocation(e.getX(), e.getY());
                                   TreePath treePath 
    = getPathForRow(row);
                                   
    if (treePath == null) {
                                           
    return;
                                   }

                                   CheckBoxTreeNode node 
    = ((CheckBoxTreeNode) treePath.getLastPathComponent());
                                   
    boolean checking = !node.isChecked(); // 如果該節點已被勾選上,則此次將取消勾選;反之,亦反。
                                   checkNode(node, checking);

                                   repaint(); 
    // 重繪整棵樹。
                           }

                           
    // 遞歸地勾選或取消勾選指定節點及其所有下級節點的CheckBox。
                           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. 設置當前節點及其子節點的勾選標記--checkNode;2. 重繪樹--repaint。調用repaint方法對樹進行繪制時,方法TreeCellRenderer.getTreeCellRendererComponent就會被調用,此時程序就會根據checkNode方法設定的isChecked來勾選或取消勾選對應的樹節點CheckBox。簡言之,就是先設置樹型數據中的勾選標記,然后渲染器再根據這些標記來渲染CheckBox。
    posted on 2009-08-05 21:10 John Jiang 閱讀(5416) 評論(3)  編輯  收藏 所屬分類: JavaSwingGUI原創

    評論

    # re: 一個簡單的CheckBox Tree實現(原)[未登錄] 2009-08-06 09:43 zeyuphoenix
    不要repaint(); // 重繪整棵樹
    這樣在很多時候都會造成cpu過高,或者莫名奇妙的繪制,我做項目遇到好幾次了
    都只能一行一行debug找,你在繼承DefaultMutableTreeNode 的類里把treenode的select方法寫的復雜一點 比如
    /**
    * set the node select.
    *
    * @param isSelected
    * node select or not.
    */
    public void setSelected(boolean isSelected) {
    this.isSelected = isSelected;

    if ((selectionMode == TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION)
    && (children != null)) {
    Enumeration<?> enumTemp = children.elements();
    while (enumTemp.hasMoreElements()) {
    MyTreeNode node = (MyTreeNode) enumTemp.nextElement();
    node.setSelected(isSelected);
    }
    }
    }
    然后在render里刷新就可以了,另外也不要繼承jcombox最好繼承jpanel這樣可以很好的以后做更復雜的添加  回復  更多評論
      

    # re: 一個簡單的CheckBox Tree實現(原) 2009-08-06 21:01 Sha Jiang
    > setSelected
    這個方法應該寫在何處?

    > 另外也不要繼承jcombox最好繼承jpanel這樣可以很好的以后做更復雜的添加
    我也知道這一點,只是在此處寫得簡單些罷了。  回復  更多評論
      

    # re: 一個簡單的CheckBox Tree實現(原) 2009-08-07 10:04 于翔
    還以為是JavaScript呢  回復  更多評論
      

    主站蜘蛛池模板: 亚洲色婷婷六月亚洲婷婷6月| 久久中文字幕免费视频| 成人au免费视频影院| 亚洲精品电影在线| 99xxoo视频在线永久免费观看| 亚洲va久久久噜噜噜久久天堂 | 精品久久香蕉国产线看观看亚洲| 免费在线看黄网站| 99re在线视频免费观看| 亚洲av无码不卡| 0588影视手机免费看片| 亚洲一区二区三区高清视频| 国产成人不卡亚洲精品91| 永久黄网站色视频免费直播| 国产AV日韩A∨亚洲AV电影| 亚洲色偷拍区另类无码专区| 激情综合亚洲色婷婷五月APP| 四虎国产精品免费久久| 日韩色日韩视频亚洲网站| 国产精品亚洲高清一区二区| 日本一区午夜艳熟免费| 亚洲av无码一区二区三区天堂古代 | 国产日韩亚洲大尺度高清| 日韩免费无码一区二区三区| 亚洲成AV人片久久| 成人永久免费福利视频网站| 亚洲高清免费视频| 久久精品九九亚洲精品| 成人男女网18免费视频| jizz免费一区二区三区| 亚洲嫩草影院在线观看| 无码国产亚洲日韩国精品视频一区二区三区| 亚洲人成电影福利在线播放 | 国产又黄又爽又猛的免费视频播放| 色屁屁www影院免费观看视频| 亚洲女同成av人片在线观看| 国产免费毛不卡片| 男女一进一出抽搐免费视频| 亚洲精品影院久久久久久| 亚洲国产小视频精品久久久三级 | 午夜在线亚洲男人午在线|