`
chenghy28
  • 浏览: 10364 次
  • 性别: Icon_minigender_1
  • 来自: 镇江
社区版块
存档分类
最新评论

TreewithCheckbox

阅读更多
package tree;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JCheckBox;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreePath;

public class CheckTreeManager extends MouseAdapter implements TreeSelectionListener{ 
    private CheckTreeSelectionModel selectionModel; 
    private JTree tree = new JTree(); 
    int hotspot = new JCheckBox().getPreferredSize().width; 
 
    public CheckTreeManager(JTree tree){ 
        this.tree = tree; 
        selectionModel = new CheckTreeSelectionModel(tree.getModel()); 
        tree.setCellRenderer(new CheckTreeCellRenderer(tree.getCellRenderer(), selectionModel)); 
        tree.addMouseListener(this); 
        selectionModel.addTreeSelectionListener(this); 
    } 
 
    public void mouseClicked(MouseEvent me){ 
        TreePath path = tree.getPathForLocation(me.getX(), me.getY()); 
        if(path==null) 
            return; 
        if(me.getX()>tree.getPathBounds(path).x+hotspot) 
            return; 
 
        boolean selected = selectionModel.isPathSelected(path, true); 
        selectionModel.removeTreeSelectionListener(this); 
 
        try{ 
            if(selected) 
                selectionModel.removeSelectionPath(path); 
            else 
                selectionModel.addSelectionPath(path); 
        } finally{ 
            selectionModel.addTreeSelectionListener(this); 
            tree.treeDidChange(); 
        } 
    } 
 
    public CheckTreeSelectionModel getSelectionModel(){ 
        return selectionModel; 
    } 
 
    public void valueChanged(TreeSelectionEvent e){ 
        tree.treeDidChange(); 
    } 
}

 

import java.awt.BorderLayout;
import java.awt.Component;

import javax.swing.JCheckBox;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;

public class CheckTreeCellRenderer extends JPanel implements TreeCellRenderer{ 
    private CheckTreeSelectionModel selectionModel; 
    private TreeCellRenderer delegate; 
    private JCheckBox checkBox = new JCheckBox(); 
   // private TristateCheckBox checkBox = new TristateCheckBox(); 
 
    public CheckTreeCellRenderer(TreeCellRenderer delegate, CheckTreeSelectionModel selectionModel){ 
        this.delegate = delegate; 
        this.selectionModel = selectionModel; 
        setLayout(new BorderLayout()); 
        setOpaque(false); 
        checkBox.setOpaque(false); 
    } 
 
 
    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus){ 
        Component renderer = delegate.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); 
 
        TreePath path = tree.getPathForRow(row); 
        if(path!=null){ 
            if(selectionModel.isPathSelected(path, true)) 
                checkBox.setSelected(Boolean.TRUE); 
            else 
                checkBox.setSelected( Boolean.FALSE); 
        } 
        removeAll(); 
        add(checkBox, BorderLayout.WEST); 
        add(renderer, BorderLayout.CENTER); 
        return this; 
    } 
}  
package tree;

import java.util.ArrayList;
import java.util.Stack;

import javax.swing.tree.DefaultTreeSelectionModel;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

public class CheckTreeSelectionModel extends DefaultTreeSelectionModel{ 
    private TreeModel model; 
 
    public CheckTreeSelectionModel(TreeModel model){ 
        this.model = model; 
        setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); 
    } 
 
    // tests whether there is any unselected node in the subtree of given path 
    public boolean isPartiallySelected(TreePath path){ 
        if(isPathSelected(path, true)) 
            return false; 
        TreePath[] selectionPaths = getSelectionPaths(); 
        if(selectionPaths==null) 
            return false; 
        for(int j = 0; j<selectionPaths.length; j++){ 
            if(isDescendant(selectionPaths[j], path)) 
                return true; 
        } 
        return false; 
    } 
 
    // tells whether given path is selected. 
    // if dig is true, then a path is assumed to be selected, if 
    // one of its ancestor is selected. 
    public boolean isPathSelected(TreePath path, boolean dig){ 
        if(!dig) 
            return super.isPathSelected(path); 
        while(path!=null && !super.isPathSelected(path)) 
            path = path.getParentPath(); 
        return path!=null; 
    } 
 
    // is path1 descendant of path2 
    private boolean isDescendant(TreePath path1, TreePath path2){ 
        Object obj1[] = path1.getPath(); 
        Object obj2[] = path2.getPath(); 
        for(int i = 0; i<obj2.length; i++){ 
            if(obj1[i]!=obj2[i]) 
                return false; 
        } 
        return true; 
    } 
 
    public void setSelectionPaths(TreePath[] pPaths){ 
        throw new UnsupportedOperationException("not implemented yet!!!"); 
    } 
 
    public void addSelectionPaths(TreePath[] paths){ 
        // unselect all descendants of paths[] 
        for(int i = 0; i<paths.length; i++){ 
            TreePath path = paths[i]; 
            TreePath[] selectionPaths = getSelectionPaths(); 
            if(selectionPaths==null) 
                break; 
            ArrayList toBeRemoved = new ArrayList(); 
            for(int j = 0; j<selectionPaths.length; j++){ 
                if(isDescendant(selectionPaths[j], path)) 
                    toBeRemoved.add(selectionPaths[j]); 
            } 
            super.removeSelectionPaths((TreePath[])toBeRemoved.toArray(new TreePath[0])); 
        } 
 
        // if all siblings are selected then unselect them and select parent recursively 
        // otherwize just select that path. 
        for(int i = 0; i<paths.length; i++){ 
            TreePath path = paths[i]; 
            TreePath temp = null; 
            while(areSiblingsSelected(path)){ 
                temp = path; 
                if(path.getParentPath()==null) 
                    break; 
                path = path.getParentPath(); 
            } 
            if(temp!=null){ 
                if(temp.getParentPath()!=null) 
                    addSelectionPath(temp.getParentPath()); 
                else{ 
                    if(!isSelectionEmpty()) 
                        removeSelectionPaths(getSelectionPaths()); 
                    super.addSelectionPaths(new TreePath[]{temp}); 
                } 
            }else 
                super.addSelectionPaths(new TreePath[]{ path}); 
        } 
    } 
 
    // tells whether all siblings of given path are selected. 
    private boolean areSiblingsSelected(TreePath path){ 
        TreePath parent = path.getParentPath(); 
        if(parent==null) 
            return true; 
        Object node = path.getLastPathComponent(); 
        Object parentNode = parent.getLastPathComponent(); 
 
        int childCount = model.getChildCount(parentNode); 
        for(int i = 0; i<childCount; i++){ 
            Object childNode = model.getChild(parentNode, i); 
            if(childNode==node) 
                continue; 
            if(!isPathSelected(parent.pathByAddingChild(childNode))) 
                return false; 
        } 
        return true; 
    } 
 
    public void removeSelectionPaths(TreePath[] paths){ 
        for(int i = 0; i<paths.length; i++){ 
            TreePath path = paths[i]; 
            if(path.getPathCount()==1) 
                super.removeSelectionPaths(new TreePath[]{ path}); 
            else 
                toggleRemoveSelection(path); 
        } 
    } 
 
    // if any ancestor node of given path is selected then unselect it 
    //  and selection all its descendants except given path and descendants. 
    // otherwise just unselect the given path 
    private void toggleRemoveSelection(TreePath path){ 
        Stack stack = new Stack(); 
        TreePath parent = path.getParentPath(); 
        while(parent!=null && !isPathSelected(parent)){ 
            stack.push(parent); 
            parent = parent.getParentPath(); 
        } 
        if(parent!=null) 
            stack.push(parent); 
        else{ 
            super.removeSelectionPaths(new TreePath[]{path}); 
            return; 
        } 
 
        while(!stack.isEmpty()){ 
            TreePath temp = (TreePath)stack.pop(); 
            TreePath peekPath = stack.isEmpty() ? path : (TreePath)stack.peek(); 
            Object node = temp.getLastPathComponent(); 
            Object peekNode = peekPath.getLastPathComponent(); 
            int childCount = model.getChildCount(node); 
            for(int i = 0; i<childCount; i++){ 
                Object childNode = model.getChild(node, i); 
                if(childNode!=peekNode) 
                    super.addSelectionPaths(new TreePath[]{temp.pathByAddingChild(childNode)}); 
            } 
        } 
        super.removeSelectionPaths(new TreePath[]{parent}); 
    } 
}

 

 使用:

   CheckTreeManager checkTreeManager = new CheckTreeManager(yourTree);

  // to get the paths that were checked
  TreePath checkedPaths[] = checkTreeManager.getSelectionModel().getSelectionPaths();

分享到:
评论

相关推荐

    Working with JavaFX UI Components.pdf

    JavaFX applications with the UI components available through the JavaFX API. 介绍了JavaFX所有UI控件。目录如下: 1. What Is New 2. Label 3. Button 4. Radio Button 5. Toggle Button 6. Checkbox 7. ...

    Visual C++ 编程资源大全(英文源码 控件)

    PropertyListCtrl.zip An object properties list control than can change based on the objects state.(64KB)&lt;END&gt;&lt;br&gt;87,supergrid.zip A combination list control and tree control with checkbox ...

    TMS Component Pack v3.7

    控件+例子以AdvStringGrid为主*****...- Fixed issue with use on FramesUpdate : TInspectorBar v1.4.0.1----------- Fixed issue with ShowFocus on checkbox items- Fixed double OnEditUpdate event for checkboxes

    FastReport 5.1.11 D7-XE7 FullSource

    - Improved checkbox control in PDF export - Fixed script inheritence - for more information see example "Report with script inheritence" - Fixed Interactive chart behaviour and added "Interactive ...

    VirtualTreeView.v.6.3.0.XE3-XE10.1

    * Implemented #607: Disabled checkbox images should be available * Fixed #612: hotkey handing and toReverseFullExpandHotKey * Fixed #602: Dangling WM_Timer and doubled OnChange calls * Fixed #...

    VirtualTreeView.v.6.3.0.XE3-XE10.1.Src

    * Implemented #607: Disabled checkbox images should be available * Fixed #612: hotkey handing and toReverseFullExpandHotKey * Fixed #602: Dangling WM_Timer and doubled OnChange calls * Fixed #...

    Radmin自动登录器v3.0-多国语言绿色版-Release1-20150615

    RecordName,IP,Port,User,Password,Domain,ColorDepth,Updates,UnlockDesktop,Fullscreen,Nofullkbcontrol,Monitor,Sendrequest,Pbpath,Proxy,AsProxyBy,Memory,TreePath sample01,192.168.0.6,4899,user01,,,,,,,...

    Radmin自动登录器v3.0

    RecordName,IP,Port,User,Password,Domain,ColorDepth,Updates,UnlockDesktop,Fullscreen,Nofullkbcontrol,Monitor,Sendrequest,Pbpath,Proxy,AsProxyBy,Memory,TreePath sample01,192.168.0.6,4899,user01,,,,,,,...

    ImpREC 1.7c

    - Checkbox "OpCodes" is enable/disable depending on "Hex View" (Thanks to Muffin) - Removed the useless '/' when there's no name (ordinal only) - Disassembler is allowed on valid slot too now...

    drools-distribution-7.10.0.Final

    Activate the checkbox of that newly created runtime environment. Restart eclipse. Open menu File, menu item Import..., tree item General, tree item Existing Projects into Workspace, button Next and ...

    plsqldev14.0.0.1961x32多语言版+sn.rar

    Define Connections and Select Connection tree was incorrect on a secondary display with different DPI settings Menu items with icons from templates were too small on high dpi monitors Ribbon / Menu ...

    plsqldev14.0.0.1961x64多语言版+sn.rar

    Define Connections and Select Connection tree was incorrect on a secondary display with different DPI settings Menu items with icons from templates were too small on high dpi monitors Ribbon / Menu ...

    VB编程资源大全(英文源码 控件)

    &lt;END&gt;&lt;br&gt;5 , vbo_checkcombo.zip Add a checkbox to a combo box and use it to enabled/disable the combo! or whatever you would like to do with it! &lt;END&gt;&lt;br&gt;6 , vbo_controlframe.zip Create your ...

    JIDE Common Layer(公共模块) 开发员技术手册(开源)

    CheckBoxList and CheckBoxTree - use check boxes inside JLists and JTrees. Calculator Component DateSpinner and PointSpinner Popup - support any popup window AutoCompletion and IntelliHints ...

    ExtAspNet_v2.3.2_dll

    ExtAspNet - ExtJS based ASP.NET Controls with Full AJAX Support ExtAspNet是一组专业的Asp.net控件库,拥有原生的AJAX支持和丰富的UI效果, 目标是创建没有ViewState,没有JavaScript,没有CSS,没有...

    jQwidgets 3.6.0

    jqxcheckbox.js: CheckBox widget jqxradiobutton.js: RadioButton widget jqxexpander.js: Expander widget jqxlistbox.js: ListBox widget jqxmaskedinput.js: Masked TextBox widget jqxmenu.js: Menu widget ...

    xplite_trial

    the checkbox in the user preference tab. Be very careful. While you will not crash your machine, you may loose a function that you didnt know you needed if you remove many of the advanced features. ...

    BUS Hound

    Checkbox options in this window are applied instantly. Numeric entries are applied by pressing the apply button, switching to another window, or exiting Bus Hound. &lt;br&gt;Buffer Size &lt;br&gt;Specifies...

    vxe-table vue表格解决方案-其他

    Basic table (基础表格)Grid (高级表格)Size (尺寸)Striped (斑马线条纹)Table with border (带边框)Cell style (单元格样式)Column resizable (列宽拖动)Maximum table height (最大高度)Resize ...

Global site tag (gtag.js) - Google Analytics