我用swing写了一个树,实现的功能就是传入一个放着map的list,根据这个list生成树,树的每个节点是一个HashMap,根据map里面的一个dm(代码)和fbdm(父辈代码)来组织树的层次结构,比如,a节点的代码是1,b节点的父辈代码是1,c节点的父辈代码也是1,那么b节点和c节点就作为a节点的子节点加到a节点下面,我现在遇到的问题是怎么递归这个节点,我写的只能做一层树结构,比如把b和c节点加到a下面我已经加成功了,但我还想把d节点加到c几点下就不行了,请高手帮我看看递归算法,不胜感激!写完马上给充50QB作为报酬,或是50RMB也行,谢谢!
代码如下:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;import javax.swing.Icon;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.plaf.ColorUIResource;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
 
 public class TreeExample extends JFrame {
    private static final long serialVersionUID = 1L;
    JTree tree;
    String title;
    ArrayList list;
    DefaultTreeModel treeModel = null;
    /*
     * 不带多选的tree构造函数
     */
    public TreeExample(String title,ArrayList list) {
        super(title);
        this.title = title;
        this.list = list;
        createTree(list);
        tree.setCellRenderer(applyTreeCellRenderer);
        treeModel = (DefaultTreeModel)tree.getModel();
        tree.getSelectionModel().setSelectionMode(
                TreeSelectionModel.SINGLE_TREE_SELECTION);
        tree.addMouseListener(new NodeSelectionListener(tree));
        JScrollPane sp = new JScrollPane(tree);
        JPanel panel = new JPanel(new BorderLayout());
        getContentPane().add(sp, BorderLayout.CENTER);
        getContentPane().add(panel, BorderLayout.EAST);       
    }
    /*
     * 带多选的tree构造函数
     */
    public TreeExample(String title,ArrayList list,boolean ischeck) {
        super(title);
        this.title = title;
        this.list = list;
        createTree(list);
        tree.setCellRenderer(new CheckRenderer());
        treeModel = (DefaultTreeModel)tree.getModel();
        tree.getSelectionModel().setSelectionMode(
                TreeSelectionModel.SINGLE_TREE_SELECTION);
        tree.addMouseListener(new NodeSelectionListener(tree));
        JScrollPane sp = new JScrollPane(tree);
        JPanel panel = new JPanel(new BorderLayout());
        getContentPane().add(sp, BorderLayout.CENTER);
        getContentPane().add(panel, BorderLayout.EAST);
        
    }
      /*
       * 将对象存在,不带check的tree节点上,显示名称
       */
     

解决方案 »

  1.   

    接上面
     /*
           * 将对象存在,不带check的tree节点上,显示名称
           */
        
      private DefaultTreeCellRenderer applyTreeCellRenderer = new DefaultTreeCellRenderer() {
        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
            super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);        DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) value;
            Object userObj = treeNode.getUserObject();        if (userObj instanceof HashMap) {
                this.setIcon(null);
                this.setText((String) ((HashMap) userObj).get("mc"));
            } 
            return this;
        }
    };
        /*
         * 循环list生成树节点,问题就出在这里
         */
        public void createTree(ArrayList ll){
         HashMap map = null ;
            CheckNode[] nodes = new CheckNode[ll.size()];   
            for(int i=0;i<nodes.length;i++){
              map = (HashMap) ll.get(i); 
              nodes[i] = new CheckNode(map);
              ArrayList l = getsubtree(map); 
              
              for(int j = 0;j<l.size();j++){
             HashMap map2 = (HashMap) l.get(j); 
                  CheckNode node = new CheckNode(map2);
                  if(node!=null){               
                   nodes[i].add(node);   
                  }
              }
              if(l!=null&&l.size()>0){
              createTree(l) ;
              }
            
                //需要根据数据的fbdm和代码相比,如果b节点的fbdm等于a节点的dm,则将b节点add到a节点下
                 if(nodes[i]!=null&&i>0&&map.get("fbdm").equals("000")){
                 nodes[0].add(nodes[i]);
                 } 
                  
            }
            tree = new JTree(nodes[0]);
      }
       /*
        * 传入一个节点,根据这个节点取它所有的子节点
        */
        public ArrayList getsubtree(HashMap m){
         ArrayList l = new ArrayList();
              String dm = (String)m.get("dm");
           for(int i=0;i<list.size();i++){
           HashMap map = (HashMap) list.get(i);
           String pdm  = (String) map.get("fbdm");
           if(pdm.equals(dm)){
           System.out.println(map.get("mc"));
           l.add(map);
           }
           }
           return l;
        } 
      
        class NodeSelectionListener extends MouseAdapter {
            JTree tree;
            NodeSelectionListener(JTree tree) {
                this.tree = tree;
            }
            public void mouseClicked(MouseEvent e) {
                //得到被选的节点
                int x = e.getX();
                int y = e.getY();
                int row = tree.getRowForLocation(x, y);           
                TreePath path = tree.getPathForRow(row);
                //判断是否单击了节点
                if (path != null) {
                    //取得被单击的节点
                    CheckNode node = (CheckNode) path.getLastPathComponent();
                    System.out.println("row====="+node.getUserObject().toString());
                    boolean isSelected = !(node.isSelected());
                    //设置被单击的节点CheckBox,使其状态与原来状态相反
                    node.setSelected(isSelected);
                    //如果节点是被选中,则展开子节点
                    if (isSelected) {
                        tree.expandPath(path);
    //                    tree.collapsePath(path);
                    }
                    //如果被选节点不是叶节点,将其所有子节点设置为CheckBox状态设成与其相同的状态
                    if(!node.isLeaf()){
                        node.getNextNode();
                        Enumeration enu= node.children();
                        while (enu.hasMoreElements()) {
                            CheckNode n = (CheckNode) enu.nextElement();
                            n.setSelected(node.isSelected());
                            if(!n.isLeaf()){
                                Enumeration enuc= n.children();
                                while (enuc.hasMoreElements()) {
                                    CheckNode c = (CheckNode) enuc.nextElement();
                                    c.setSelected(node.isSelected());
                                }
                            }
                        }
                    }
                    //刷新树
                    ((DefaultTreeModel) tree.getModel()).nodeChanged(node); 
                    tree.revalidate();
                    tree.repaint();    
                }
            }
        }
        public static void main(String args[]) throws Exception {
         
         ArrayList list = new ArrayList();
         HashMap m  = new HashMap();
         m.put("mc","父");
         m.put("dm","001");
         m.put("fbdm","000");
         m.put("bm","001001");
         HashMap m2  = new HashMap();
         m2.put("mc","孩子1");
         m2.put("dm","001");
         m2.put("fbdm","000");
         m2.put("bm","001002");
         HashMap m3  = new HashMap();
         m3.put("mc","孩子2");
         m3.put("dm","002");
         m3.put("fbdm","000");
         m3.put("bm","001003");
         HashMap m4  = new HashMap();
         m4.put("mc","孙子1");
         m4.put("dm","003");
         m4.put("fbdm","002");
         m4.put("bm","001004");
         HashMap m5  = new HashMap();
         m5.put("mc","孙子2");
         m5.put("dm","005");
         m5.put("fbdm","002");
         m5.put("bm","001005");
         HashMap m6  = new HashMap();
         m6.put("mc","曾孙");//问题就在这里它应该作为孙子2的子结点放在孙子2下面的,但没有放
         m6.put("dm","006");
         m6.put("fbdm","005");
         m6.put("bm","001006");
         list.add(m);
         list.add(m2);
         list.add(m3);
         list.add(m4);
         list.add(m5);
         list.add(m6);
            TreeExample frame = new TreeExample("树",list,true);
            File file = new File("TreeExample.java");
           
                System.out.println("   " + file.getCanonicalPath());
            frame.addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                    System.exit(0);
                }
            });
            frame.setSize(300, 200);
            frame.setVisible(true);
        }
    }
      

  2.   

    接上面
    class CheckRenderer extends JPanel implements TreeCellRenderer {
        //树的节点JPanel编辑,每个节点都是一个JPanel,JPanel中有一个JCheckBox和一个JLabel
        //TreeCellRenderer从DefaultMutableTreeNode(即CheckNode)中取得数据设置节点
        //TreeCellRenderer主要设置Tree的外观,
        protected JCheckBox check;
        protected TreeLabel label;
        public CheckRenderer() {
            setLayout(null);
            add(check = new JCheckBox());
            add(label = new TreeLabel());
            check.setBackground(UIManager.getColor("Tree.textBackground"));
            label.setForeground(UIManager.getColor("Tree.textForeground"));
        }
        public Component getTreeCellRendererComponent(JTree tree, Object value,
                boolean isSelected, boolean expanded, boolean leaf, int row,
                boolean hasFocus) {        DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) value;
            Object userObj = treeNode.getUserObject();        if (userObj instanceof HashMap) {
                label.setText(((HashMap)userObj).get("mc").toString());
            } 
            String stringValue = tree.convertValueToText(value, isSelected,
                    expanded, leaf, row, hasFocus);
            setEnabled(tree.isEnabled());
            check.setSelected(((CheckNode) value).isSelected());
            label.setFont(tree.getFont());
          //  label.setText(stringValue);
            label.setSelected(isSelected);
            label.setFocus(hasFocus);
            if (leaf) {
                if(((CheckNode) value).getIcon()!=null){
                    label.setIcon(((CheckNode) value).getIcon());
                }else{
                    label.setIcon(UIManager.getIcon("Tree.leafIcon"));
                }
                
            } else if (expanded) {
                label.setIcon(UIManager.getIcon("Tree.openIcon"));
            } else {
                label.setIcon(UIManager.getIcon("Tree.closedIcon"));
            }
            return this;
        }
        //获取结点大小
        public Dimension getPreferredSize() {
            Dimension d_check = check.getPreferredSize();
            Dimension d_label = label.getPreferredSize();
            return new Dimension(d_check.width + d_label.width,
                    (d_check.height < d_label.height ? d_label.height
                            : d_check.height));
        }
        //布局check和label
        public void doLayout() {
            Dimension d_check = check.getPreferredSize();
            Dimension d_label = label.getPreferredSize();
            int y_check = 0;
            int y_label = 0;
            if (d_check.height < d_label.height) {
                y_check = (d_label.height - d_check.height) / 2;
            } else {
                y_label = (d_check.height - d_label.height) / 2;
            }
            check.setLocation(0, y_check);
            check.setBounds(0, y_check, d_check.width, d_check.height);
            label.setLocation(d_check.width, y_label);
            label.setBounds(d_check.width, y_label, d_label.width, d_label.height);
        }
        //设置背景颜色
        public void setBackground(Color color) {
            if (color instanceof ColorUIResource)
                color = null;
            super.setBackground(color);
        }    public class TreeLabel extends JLabel {
            boolean isSelected;
            boolean hasFocus;
            public TreeLabel() {
            }
            public void setBackground(Color color) {
                if (color instanceof ColorUIResource)
                    color = null;
                super.setBackground(color);
            }        public void paint(Graphics g) {
                String str;
                if ((str = getText()) != null) {
                    if (0 < str.length()) {
                        if (isSelected) {
                            g.setColor(UIManager
                                    .getColor("Tree.selectionBackground"));
                        } else {
                            g.setColor(UIManager.getColor("Tree.textBackground"));
                        }
                        Dimension d = getPreferredSize();
                        int imageOffset = 0;
                        Icon currentI = getIcon();
                        if (currentI != null) {
                            imageOffset = currentI.getIconWidth()
                                    + Math.max(0, getIconTextGap() - 1);
                        }
                        g.fillRect(imageOffset, 0, d.width - 1 - imageOffset,
                                d.height);
                        if (hasFocus) {
                            g.setColor(UIManager
                                    .getColor("Tree.selectionBorderColor"));
                            g.drawRect(imageOffset, 0, d.width - 1 - imageOffset,
                                    d.height - 1);
                        }
                    }
                }
                super.paint(g);
            }        public Dimension getPreferredSize() {
                Dimension retDimension = super.getPreferredSize();
                if (retDimension != null) {
                    retDimension = new Dimension(retDimension.width + 3,
                            retDimension.height);
                }
                return retDimension;
            }        public void setSelected(boolean isSelected) {
                this.isSelected = isSelected;
            }        public void setFocus(boolean hasFocus) {
                this.hasFocus = hasFocus;
            }
        }
    }//结点数据类
    class CheckNode extends DefaultMutableTreeNode {
        private int selectionMode = 0;
        private boolean isSelected = false;
        private Icon icon = null;
        private String name;
        static HashMap map; 
        public CheckNode() {
            this(null);
        } public CheckNode(Object userObject) {
            this(userObject, true, false,map);
          
        }
       
        public CheckNode(Object userObject, boolean allowsChildren,
                boolean isSelected,HashMap map) {
            super(userObject, allowsChildren);
            this.isSelected = isSelected;
            this.map = map;
        }
        public void setName(String name) {
    this.name = name;
    }  
        public int getSelectionMode() {
            return selectionMode;
        }    public void setSelected(boolean isSelected) {
            this.isSelected = isSelected;
        }    public boolean isSelected() {
            return isSelected;
        }
        
        public void setIcon(Icon icon){
            this.icon = icon;
        }
        
        public Icon getIcon(){
            return icon;
        }
        public String getName(){
         name = (String)map.get("mc");
         return name;
        }
    }
      

  3.   

    修改createTree方法,添加一个addChild方法
             private void addChild(CheckNode fatherNode,ArrayList l) {
    HashMap map = null;
    for (int i = 0; i < l.size(); i++) {
    map = (HashMap) l.get(i);
    CheckNode child = new CheckNode(map);
    ArrayList ll = getsubtree(map);
    fatherNode.add(child);
    addChild(child,ll);
    }

    } public void createTree(ArrayList ll) {
    HashMap map = null;
    CheckNode top = null;
    for (int i = 0; i < ll.size(); i++) {
    map = (HashMap) ll.get(i);
    if (map.get("fbdm").equals("000")) {
    top = new CheckNode(map);
    ArrayList l = getsubtree(map);
    addChild(top,l);
    } }
    tree = new JTree(top);
    }
    另外,你的构造树的方法也不对,用下面的方式构造
    ArrayList list = new ArrayList();
    HashMap m = new HashMap();
    m.put("mc", "fu");
    m.put("dm", "001");
    m.put("fbdm", "000");
    m.put("bm", "001001");
    HashMap m2 = new HashMap();
    m2.put("mc", "haizi1");
    m2.put("dm", "002");
    m2.put("fbdm", "001");
    m2.put("bm", "001002");
    HashMap m3 = new HashMap();
    m3.put("mc", "haizi2");
    m3.put("dm", "003");
    m3.put("fbdm", "001");
    m3.put("bm", "001003");
    HashMap m4 = new HashMap();
    m4.put("mc", "sunzi1");
    m4.put("dm", "004");
    m4.put("fbdm", "003");
    m4.put("bm", "001004");
    HashMap m5 = new HashMap();
    m5.put("mc", "sunzi2");
    m5.put("dm", "005");
    m5.put("fbdm", "003");
    m5.put("bm", "001005");
    HashMap m6 = new HashMap();
    m6.put("mc", "zengsun");
    m6.put("dm", "006");
    m6.put("fbdm", "005");
    m6.put("bm", "001006");
    list.add(m);
    list.add(m2);
    list.add(m3);
    list.add(m4);
    list.add(m5);
    list.add(m6);
      

  4.   

    我也看了下
    感觉问题有两处,一处是测试用例(父亲的dm应该是'000',fbdm就不能是'000'了),
    另一处就是你的递归,递归遍历树需要递归的时候建立
    另外我写了个递归的函数,调用的时候需要这样:tree=new JTree( createTree(list,null,null));
            /* 
            * 循环list生成树节点,问题就出在这里 
            */ 
            public CheckNode createTree(ArrayList ll,CheckNode root,HashMap map){ 
            
             //递归入口 
                 if (root==null) {
                 map=(HashMap)ll.get(0);
                 root=new CheckNode(map);             }
                  //获得子节点集合
                   ArrayList l = getsubtree(map); 
                   
                   //循环子节点建立父子关系并且递归遍历
                   for(int j = 0;j <l.size();j++){ 
                HashMap tempmap = (HashMap) l.get(j); 
                    CheckNode tempnode = new CheckNode(tempmap); 
                    if(tempnode!=null){            
                     root.add(tempnode);  
                      createTree(l,tempnode,tempmap) ; 
                    }        
                }       
                      return root;
                }