<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

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

    實(shí)現(xiàn)CheckBox Tree的常用方法,就是使用JCheckBox作為JTree的TreeCellRendrer,并且需要實(shí)現(xiàn)特定的Checking規(guī)則來勾選/取消勾選CheckBox。

    1. 樹節(jié)點(diǎn)
    DefaultMutableTreeNode是最常用的TreeNode實(shí)現(xiàn),此處我們將擴(kuò)展這一實(shí)現(xiàn)--CheckBoxTreeNode,增加一個屬性isChecked,用于標(biāo)識該節(jié)點(diǎn)是否要被勾選上。該類的完整代碼如下所示:
    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作為樹節(jié)點(diǎn)展現(xiàn)形式的渲染器,同時確定對節(jié)點(diǎn)進(jìn)行勾選或取消勾選的規(guī)則。CheckBoxTreeCellRenderer本身即是一個JCheckBox,那么在實(shí)現(xiàn)getTreeCellRendererComponent方法時,只簡單地返回它自己的實(shí)例即可,而對于勾選或取消勾選的條件,則由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); // 獲取樹節(jié)點(diǎn)對象。
                   setText(node.toString()); // 設(shè)置CheckBox所展示的文本。

                   
    // 當(dāng)樹節(jié)點(diǎn)被設(shè)置為勾選時,則該節(jié)點(diǎn)對應(yīng)的CheckBox被勾選上;否則,取消勾選。
                   if (node.isChecked()) {
                           setSelected(
    true);
                           setForeground(Color.BLUE);
                   } 
    else {
                           setSelected(
    false);
                           setForeground(tree.getForeground());
                   }
                   
    return this;
           }
    }

    3. 樹
    此處對JTree進(jìn)行擴(kuò)展,創(chuàng)建CheckBoxTree,該類只是為JTree添加了一個MouseListener,以偵聽鼠標(biāo)選中樹節(jié)點(diǎn)后,如何設(shè)置勾選標(biāo)記,并重繪樹。
    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(); // 如果該節(jié)點(diǎn)已被勾選上,則此次將取消勾選;反之,亦反。
                                   checkNode(node, checking);

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

                           
    // 遞歸地勾選或取消勾選指定節(jié)點(diǎn)及其所有下級節(jié)點(diǎn)的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);
                                           }
                                   }
                           }
                   });
           }
    }
    上述程序有兩個關(guān)鍵點(diǎn):1. 設(shè)置當(dāng)前節(jié)點(diǎn)及其子節(jié)點(diǎn)的勾選標(biāo)記--checkNode;2. 重繪樹--repaint。調(diào)用repaint方法對樹進(jìn)行繪制時,方法TreeCellRenderer.getTreeCellRendererComponent就會被調(diào)用,此時程序就會根據(jù)checkNode方法設(shè)定的isChecked來勾選或取消勾選對應(yīng)的樹節(jié)點(diǎn)CheckBox。簡言之,就是先設(shè)置樹型數(shù)據(jù)中的勾選標(biāo)記,然后渲染器再根據(jù)這些標(biāo)記來渲染CheckBox。
    posted on 2009-08-05 21:10 John Jiang 閱讀(5431) 評論(3)  編輯  收藏 所屬分類: Java 、Swing 、GUI 、原創(chuàng)

    評論

    # re: 一個簡單的CheckBox Tree實(shí)現(xiàn)(原)[未登錄] 2009-08-06 09:43 zeyuphoenix
    不要repaint(); // 重繪整棵樹
    這樣在很多時候都會造成cpu過高,或者莫名奇妙的繪制,我做項(xiàng)目遇到好幾次了
    都只能一行一行debug找,你在繼承DefaultMutableTreeNode 的類里把treenode的select方法寫的復(fù)雜一點(diǎn) 比如
    /**
    * 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這樣可以很好的以后做更復(fù)雜的添加  回復(fù)  更多評論
      

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

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

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

    主站蜘蛛池模板: 朝桐光亚洲专区在线中文字幕 | 免费看的黄色大片| 亚洲精品视频免费在线观看| 亚洲免费视频网址| 亚洲国产人成网站在线电影动漫| 亚洲色欲色欲综合网站| 免费视频精品一区二区三区| 亚洲国产精品一区第二页| a毛片在线免费观看| 久久精品国产亚洲| 麻花传媒剧在线mv免费观看 | 无码欧精品亚洲日韩一区| 久久青草免费91线频观看不卡 | 亚洲熟妇无码AV不卡在线播放| 久久久久国色AV免费观看性色 | 无码国产精品一区二区免费16| 久久精品国产亚洲av影院| 最近2019中文字幕免费大全5| 亚洲综合免费视频| 在人线av无码免费高潮喷水| 在线观看亚洲AV日韩AV| 免费一级毛片在级播放| 两性色午夜免费视频| 久久精品蜜芽亚洲国产AV| 美女被免费视频网站a国产| 免费无码专区毛片高潮喷水 | 四虎免费在线观看| 日韩亚洲人成网站| 精品久久香蕉国产线看观看亚洲| 91福利视频免费观看| 亚洲欧美日韩中文无线码 | 无遮挡免费一区二区三区 | 国产aⅴ无码专区亚洲av| 24小时在线免费视频| 亚洲av无码兔费综合| 亚洲精品高清国产一线久久| 永久免费毛片在线播放| 特级无码毛片免费视频| 色婷婷六月亚洲婷婷丁香| 四虎在线免费播放| 蜜桃视频在线观看免费视频网站WWW |