package com.test;


import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Stack;

import javax.swing.JCheckBox;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultTreeSelectionModel;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;


public class AddCheckBoxToTree {
	

 class CheckTreeSelectionModel extends DefaultTreeSelectionModel{ 
    static final  long serialVersionUID =0;
    private TreeModel model; 

    public CheckTreeSelectionModel(TreeModel model){ 
        this.model = model; 

        setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); 
    }       
    //get the selected paths
    public List<String> getSelectedPaths(){
    	List<String> pathList=new ArrayList<String>();
        TreePath[] selectionPaths = getSelectionPaths(); 
        for(TreePath t:selectionPaths){
        	Object lastNode=t.getLastPathComponent();
        	int nodeLevel=t.getPathCount();
        	TreeNode node=(TreeNode) t.getLastPathComponent();
        	//if(nodeLevel!=0)
        	//pathList.add(t.getLastPathComponent().toString());
        	//JOptionPane.showMessageDialog(null,         	+"====");
        	int count=model.getChildCount(node);
        	for(int i=0;i<count;i++){
        		
        	 TreeNode childNode=	(TreeNode) model.getChild(node, i);
        	 if(childNode.getChildCount()==0)
        	 pathList.add( model.getChild(node, i).toString());
            	}
        }
        
        
        return pathList;
    }
    
	StringBuffer nodeList=new StringBuffer();
    
    //get all nodes which is selected By DiGui
    
	
	
	private void addNodesByDiGui(MyDefaultTreeModel node,String split){
		int count=model.getChildCount(node);
		if(null!=node.getParent()){
		nodeList.append( node.getTreeId()).append(split);
		}
		for(int i=0;i<count;i++){
    		MyDefaultTreeModel childNode=	(MyDefaultTreeModel) model.getChild(node, i);
    	 String s=childNode.getTreeId();
    	 if(model.getChildCount(childNode)!=0){
    		 addNodesByDiGui(childNode,split);
    	 }
    	  	 if(null!=s){
    		 nodeList.append( s).append(split);
    		 
    	 }
		}
		
		
	}
	
    private void addNodesToLists(String split){
    	 TreePath[] selectionPath = getSelectionPaths(); 
        for(TreePath t:selectionPath){
        	MyDefaultTreeModel node=(MyDefaultTreeModel) t.getLastPathComponent();
        	addNodesByDiGui(node,split);
        	
        }
    
    	
    }
    
    
	
    private void addNodesToLists1(String split){
    	 TreePath[] selectionPath = getSelectionPaths(); 
        for(TreePath t:selectionPath){
        	TreeNode node=(TreeNode) t.getLastPathComponent();
        	//if(nodeLevel!=0)
        	//pathList.add(t.getLastPathComponent().toString());
        	//JOptionPane.showMessageDialog(null,         	+"====");
        	int count=model.getChildCount(node);
        	for(int i=0;i<count;i++){
        	 TreeNode childNode=	(TreeNode) model.getChild(node, i);
        	 
        	 if(   	model.getChildCount(childNode)==0){
        		 String s=model.getChild(node, i).toString();
        	 if(!s.equals("true")&&!s.equals("false"))
        		//JOptionPane.showMessageDialog(null, model.getChild(node, i)+"====");
        	 nodeList.append( model.getChild(node, i).toString());
        	 
     
        	 
        	 }
        	
            	}
        }
        
    
    	
    	
    }
    
    
    
    
    //return all selected nodes
    public String getSelectedNodes(String split){
    	nodeList.delete(0, nodeList.length());
    	addNodesToLists(split);
    	return nodeList.toString().substring(0, nodeList.toString().length()-1);
    }
 
    // tests whether there is any unselected node in the subtree of given path (DONT_CARE)
    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<TreePath> toBeRemoved = new ArrayList<TreePath>(); 

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

        Boolean isParameters = false;
        Boolean isDescription = false;

        for(int i = 0; i<childCount; i++){ 

            Object childNode = model.getChild(parentNode, i); 



            if(childNode==node){ 
                continue;
            }

// If last Path component equals to "parameters" or "description" - select second child too. 
            if(childCount == 2)
            {
                if(childNode.toString().equals("parameters") && model.isLeaf(childNode))
                {
                    isParameters = true;
                }
                if(childNode.toString().equals("description") && model.isLeaf(childNode))
                {
                    isDescription = true;
                }
            }


            if(!isPathSelected(parent.pathByAddingChild(childNode)) && !isParameters && !isDescription){ 
                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<TreePath> stack = new Stack<TreePath>(); 
        TreePath parent = path.getParentPath(); 

        Boolean isParameters = false;
        Boolean isDescription = false;

        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.toString().equals("parameters") && model.isLeaf(childNode))
                {
                    isParameters = true;
                }
                if(childNode.toString().equals("description")  && model.isLeaf(childNode))
                {
                    isDescription = true;
                }


                if(childNode!=peekNode)
                {
                    if(!isParameters && !isDescription)
                    super.addSelectionPaths(new TreePath[]{temp.pathByAddingChild(childNode)}); 
                }
            } 
        } 

        super.removeSelectionPaths(new TreePath[]{parent}); 
    }

    public TreeModel getModel() {
        return model;
    } 
}


public class CheckTreeCellRenderer extends JPanel implements TreeCellRenderer { 

    static final  long serialVersionUID =0;

    CheckTreeSelectionModel selectionModel; 
    private TreeCellRenderer delegate; 
    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.setState(checkBox.SELECTED);   
                //System.out.println(">>>>>>     selected   " );
            }
            else
            {                       
                checkBox.setState(checkBox.NOT_SELECTED);   
                //System.out.println("not selected   ");
            }

            if(selectionModel.isPartiallySelected(path))
            {
              //  checkBox.setState(checkBox.DONT_CARE);                  
            }
        } 

        removeAll();        

            add(checkBox, BorderLayout.WEST); 
            add(renderer, BorderLayout.CENTER);     


        return this; 
    }


    public TreeCellRenderer getDelegate() {
        return delegate;
    }


    public void setDelegate(TreeCellRenderer delegate) {
        this.delegate = delegate;
    } 
} 


public class CheckTreeManager extends MouseAdapter implements TreeSelectionListener{ 
	
	
    CheckTreeSelectionModel selectionModel; 
    private JTree tree = new JTree(); 

    int hotspot = new JCheckBox().getPreferredSize().width; 

    public CheckTreeManager(JTree tree, CheckTreeSelectionModel checkTreeSelectionModel){ 
        this.tree = tree;           


        if(checkTreeSelectionModel != null)
        {
            //selectionModel = new CheckTreeSelectionModel(tree.getModel()); 
            selectionModel =  checkTreeSelectionModel;

        }
        else
        {
            selectionModel = new CheckTreeSelectionModel(tree.getModel()); 
            //System.out.println(selectionModel.getSelectionPath());
        }



        tree.setCellRenderer(new CheckTreeCellRenderer(tree.getCellRenderer(), selectionModel)); 

        tree.addMouseListener(this); 
        selectionModel.addTreeSelectionListener(this); 
    } 

    
    public void mouseClicked(MouseEvent me){ 
        //System.out.println("start...");
        TreePath path = tree.getPathForLocation(me.getX(), me.getY()); 
        
        //System.out.println(Arrays.asList(path));

       
        if(path==null) 
        {
            //System.out.println("path==null");
            return;     
        }

        if(me.getX()/1.2>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 setSelectionModel(CheckTreeSelectionModel selectionModel) {
        this.selectionModel = selectionModel;
    }

    public void valueChanged(TreeSelectionEvent e){ 
        tree.treeDidChange(); 
    }       
}    
}
最近下载更多
sckj_01  LV1 2023年5月2日
512816870  LV2 2022年9月8日
hg2370634854  LV2 2022年4月11日
antiwise  LV1 2022年1月10日
the_teenagers  LV1 2021年7月20日
有人ʰ 2021年7月15日
暂无贡献等级
zxc12188  LV1 2021年6月15日
zhu9527  LV2 2021年5月31日
李先生很好。  LV1 2021年3月27日
lizhenlinok  LV10 2021年1月11日
最近浏览更多
lcsking 昨天
暂无贡献等级
754210352  LV1 3月26日
辰槿de星星  LV2 2023年11月10日
漫步的海星  LV4 2023年8月28日
sckj_01  LV1 2023年5月2日
512816870  LV2 2022年9月8日
hg2370634854  LV2 2022年4月11日
微信网友_5852742079762432  LV6 2022年3月5日
一起吹过晚风的街  LV1 2022年1月17日
antiwise  LV1 2022年1月10日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友