举个例子,比如我的JTree显示的一系列菜单,就是每个叶子是按级次的菜单项。每个菜单项前面有个标识(图片类似于JCheckbox,想在JTree的叶子里加JCheckbox,不过好像不行,只能换成类似的图片)来记录该菜单是不是被选择的。如果单击,该项菜单被选择,再单击,取消选择。

解决方案 »

  1.   

    可以用JCheckbox啊,等一下我给你写个例子
      

  2.   

    yuanmeng163(今天我有空),可以用JCheckbox?你有oicq吗?
    要是解决能这个问题,实在太感谢了!
      

  3.   

    给你个示例参考一下:DefaultTreeCellRenderer cellRenderer = (DefaultTreeCellRenderer)tree.getCellRenderer();//利用JTree的getCellRenderer()方法取得DefaultTreeCellRenderer对象
            
            cellRenderer.setLeafIcon(new ImageIcon(".\\icons\\leaf.gif"));  //分别设置目录树叶节点,打开,关闭的图案。
            cellRenderer.setOpenIcon(new ImageIcon(".\\icons\\open.gif"));  
            cellRenderer.setClosedIcon(new ImageIcon(".\\icons\\close.gif"));        cellRenderer.setFont(new Font("宋体",Font.PLAIN,12));       //设置字体
            
            cellRenderer.setBackgroundNonSelectionColor(Color.white);   //设置选或不选时,节点的底色,边界颜色
            cellRenderer.setBackgroundSelectionColor(Color.yellow);
            cellRenderer.setBorderSelectionColor(Color.red);
            
            cellRenderer.setTextNonSelectionColor(Color.black); //设置选或不选时,文字的变化颜色。
            cellRenderer.setTextSelectionColor(Color.blue);在树中的public void valueChanged(TreeSelectionEvent e) 中改变图片吧
      

  4.   

    谢谢cooled(经典中--经过非典中) 
    tree.getCellRenderer();会得到所有的renderer,所以只能设置同时所有的节点,我要根据状态不同,不通的节点设置不同的图片,其实就是要用checkbox放在叶子的前面。
      

  5.   

    不好意思,可以做到把JCheckBox放在叶子前面,但不能做到对每一个叶子前面的JCheckBox进行操作,也就是说只能做到全部选中或全部不选中。
      

  6.   

    Athene(菜菜子) 
    修改前可以先用isLeaf(方法判断是否是叶子节点。
    或继承DefaultMutableTreeNode类,增加一个节点类型字段。
      

  7.   

    不难,可以重载renderer的getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus)方法。根据传入的value的种类,来设定不同的图标和其他属性。
    //inner class MyDefaultTreeCellRenderer that modify cell renderer
      private class MyDefaultTreeCellRenderer extends DefaultTreeCellRenderer
      {
        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected,
             boolean expanded, boolean leaf, int row, boolean hasFocus)
        {
          DefaultMutableTreeNode node=(DefaultMutableTreeNode)value;
           if(node instanceof MyDefaultMutableTreeNode && leaf == true)
           {
             setText(((MyDefaultMutableTreeNode)node).getText());
             setIcon(((MyDefaultMutableTreeNode)node).getIcon());
             //这里针对单个节点还可以进行其他设置....
           }       setIcon(new ImageIcon("images\\right02.gif"));
           setIcon(new ImageIcon("images\\down02.gif"));       return this;
        }
      }
     //inner class MyTreeModel that modify tree node
      protected class MyDefaultMutableTreeNode extends DefaultMutableTreeNode
      {
        User user = (User)(this.getUserObject());
        ImageIcon icon = user.getIcon();    MyDefaultMutableTreeNode(Object object, boolean allowChildren)
        {
          super(object, allowChildren);
        }    //get the string representative of the user object
        String getText()
        {
          return this.toString();
        }
        //get the icon of the user object
        ImageIcon getIcon()
        {
          return icon;
        }
      }
      

  8.   

    想了想,继承DefaultMutableTreeNode后再继承DefaultTreeCellRenderer类:public Component getTreeCellRendererComponent(JTree tree, Object value,boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus){
    String stringValue = tree.convertValueToText(value, sel,expanded, leaf, row, hasFocus);
            this.hasFocus = hasFocus;
            setText(stringValue);
            if(sel) {setForeground(getTextSelectionColor());
                //...
                //根据节点类型判断是否修改图片
            }else{
               setForeground(getTextNonSelectionColor());
               //...
               //根据节点类型判断是否修改图片 
            }
            if (tree.isEnabled()) {
                setEnabled(true);
                if (value==null) return null;
                myTreeNode node = (myTreeNode)value;
                int nType = node.getTreeNodeType();//继承的DefaultMutableTreeNode类中添加的方法,返回节点类型            switch(nType){//根据节点类型分别设置不同图片
                    case ...
                        setIcon(new ImageIcon(rootNodeImageUrl)); //root
                        break;
                    case ...
                        setIcon(new ImageIcon(...)); 
                        break;
                    case ...:
                        setIcon(new ImageIcon(...)); 
                        break;
                    ...
                }
            }
            setComponentOrientation(tree.getComponentOrientation());
            selected = sel;        return this;
        }
      

  9.   

    to:mercury1231(非典时期的爱情)
    想不到方法已经出来了,hoho~
      

  10.   

    我现在想在每个节点前面加一个JCheckBox,是不是也可以实现?具体该怎么做呢?
      

  11.   

    用上面给的例子,在new一个树节点时指定它的类型就可以了,
    然后按类型分别用不同的图片.
      

  12.   

    to: cooled(经典中--经过非典中) 
    我不想用图片,不能直接在叶子前加JCheckbox吗?急切要解决这个问题,你有oicq嘛?能请教你吗?你要是在北京的话,可以请你吃饭,:)
      

  13.   

    可以加个JCheckBox,我做好了。但是正如我前面所讲的,每个JCheckBox想单独响应事件的话就比较困难了。
      

  14.   

    我查了文档,jb7提供了一个CheckTree类,在jBuilder.jar中,用法可以查文档,下面是我写的一个例子:import javax.swing.*;
    import javax.swing.tree.*;
    import com.borland.primetime.ui.*;
    import java.awt.*;
    public class CheckTreeTest extends JPanel{
        JTree optionTree = new CheckTree();
        OptionTreeNode root = new OptionTreeNode("Root", false, null);
        OptionTreeNode optionsGroup = new OptionTreeNode("Options", false, root);
        OptionTreeNode test1 = new OptionTreeNode("testNode1", true,optionsGroup);
        OptionTreeNode test2 = new OptionTreeNode("testNode2", true,optionsGroup);
        OptionTreeNode test3 = new OptionTreeNode("testNode3", true,optionsGroup);
        DefaultTreeModel model = new DefaultTreeModel(root);
        private BorderLayout borderLayout1 = new BorderLayout();    public CheckTreeTest() {
            try  {
                jbInit();
            }
            catch(Exception ex) {
                ex.printStackTrace();
            }
        }    void jbInit() throws Exception {
            // build UI
            optionTree.setModel(model);
            this.setLayout(borderLayout1);
            this.add(optionTree, BorderLayout.CENTER);
        }    public class OptionTreeNode extends CheckTreeNode {
            public OptionTreeNode(String label, boolean isCheckable, OptionTreeNode parent) {
                super(label, isCheckable);
                setText(label);
                if (parent != null) {
                    parent.add(this);
                }
            }
        }    /**输出信息*/
        public void writeProperties() {
            optionTree.stopEditing();
            System.out.println("Show error messages " + test1.isChecked());
        }    public void readProperties() {
            optionTree.stopEditing();
            test1.setChecked(false);
        }    public static void main(String[] args) {
            CheckTreeTest checkTreeTest1 = new CheckTreeTest();
            JFrame jf = new JFrame("testCheckTree");
            jf.getContentPane() .add(checkTreeTest1);
            jf.pack();
            jf.setVisible(true);
        }}我看了uml图CheckTreeNode继承了DefaultMutableTreeNode,单独响应事件没问题
      

  15.   

    谢谢各位,同 flybait(奔笨) ,要是公开原码,感激不尽,
    还有饭局!