mport java.io.*;
import java.util.*;
import javax.swing.tree.*;
import jp.gr.java_conf.tame.swing.attribute.*;
/**
 * @version 1.0 01/11/99
 */
public class CheckNode extends DefaultMutableTreeNode {  public final static int SINGLE_SELECTION = 0;
  public final static int DIG_IN_SELECTION = 4;
  protected int selectionMode;
  protected boolean isSelected;  public CheckNode() {
    this(null);
  }  public CheckNode(Object userObject) {
    this(userObject, true, false);
  }  public CheckNode(Object userObject, boolean allowsChildren
                                    , boolean isSelected) {
    super(userObject, allowsChildren);
    this.isSelected = isSelected;
    setSelectionMode(DIG_IN_SELECTION);
  }
  public void setSelectionMode(int mode) {
    selectionMode = mode;
  }  public int getSelectionMode() {
    return selectionMode;
  }  public void setSelected(boolean isSelected) {
    this.isSelected = isSelected;
    
    if ((selectionMode == DIG_IN_SELECTION)
        && (children != null)) {
      Enumeration enum = children.elements();      
      while (enum.hasMoreElements()) {
        CheckNode node = (CheckNode)enum.nextElement();
        node.setSelected(isSelected);
      }
    }
  }
  
  public boolean isSelected() {
    return isSelected;
  }
  // If you want to change "isSelected" by CellEditor,
  /*
  public void setUserObject(Object obj) {
    if (obj instanceof Boolean) {
      setSelected(((Boolean)obj).booleanValue());
    } else {
      super.setUserObject(obj);
    }
  }
  */}

解决方案 »

  1.   

    /* (swing1.1) */
    //package jp.gr.java_conf.tame.swing.examples;import java.util.*;
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.tree.*;
    import javax.swing.event.*;
    import javax.swing.border.*;import jp.gr.java_conf.tame.swing.tree.*;/**
     * @version 1.1 01/15/99
     */
    public class CheckNodeTreeExample extends JFrame {
      
      public CheckNodeTreeExample() {
        super("CheckNode TreeExample");
        String[] strs = {"swing",     // 0
         "platf",     // 1
         "basic",     // 2
         "metal",     // 3
         "JTree"};    // 4
                                                 
        CheckNode[] nodes = new CheckNode[strs.length];
        for (int i=0;i<strs.length;i++) {
          nodes[i] = new CheckNode(strs[i]); 
        }
        nodes[0].add(nodes[1]);
        nodes[1].add(nodes[2]);
        nodes[1].add(nodes[3]);
        nodes[0].add(nodes[4]);
        nodes[3].setSelected(true);
        JTree tree = new JTree( nodes[0] );
        tree.setCellRenderer(new CheckRenderer());
        tree.getSelectionModel().setSelectionMode(
          TreeSelectionModel.SINGLE_TREE_SELECTION
        );
        tree.putClientProperty("JTree.lineStyle", "Angled");
        tree.addMouseListener(new NodeSelectionListener(tree));
        JScrollPane sp = new JScrollPane(tree);
        
        ModePanel mp = new ModePanel(nodes);
        JTextArea textArea = new JTextArea(3,10);
        JScrollPane textPanel = new JScrollPane(textArea);
        JButton button = new JButton("print");
        button.addActionListener(
          new ButtonActionListener(nodes[0], textArea));
        JPanel panel = new JPanel(new BorderLayout());
        panel.add(mp,     BorderLayout.CENTER);
        panel.add(button, BorderLayout.SOUTH);
        
        getContentPane().add(sp,    BorderLayout.CENTER);
        getContentPane().add(panel, BorderLayout.EAST);
        getContentPane().add(textPanel, BorderLayout.SOUTH);
      }  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);
          //TreePath  path = tree.getSelectionPath();
          if (path != null) {
            CheckNode node = (CheckNode)path.getLastPathComponent();
            boolean isSelected = ! (node.isSelected());
            node.setSelected(isSelected);
            if (node.getSelectionMode() == CheckNode.DIG_IN_SELECTION) {
              if ( isSelected ) {
                tree.expandPath(path);
              } else {
                tree.collapsePath(path);
              }
            }
            ((DefaultTreeModel)tree.getModel()).nodeChanged(node);
            // I need revalidate if node is root.  but why?
            if (row == 0) {
              tree.revalidate();
              tree.repaint();
            }
          }
        }
      }
      
      class ModePanel extends JPanel implements ActionListener {
        CheckNode[] nodes;
        JRadioButton b_single,  b_dig_in;
        
        ModePanel(CheckNode[] nodes) {
          this.nodes = nodes;
          setLayout(new GridLayout(2,1));
          setBorder(new TitledBorder("Check Mode"));
          ButtonGroup group = new ButtonGroup();
          add(b_dig_in = new JRadioButton("DIG_IN  "));
          add(b_single = new JRadioButton("SINGLE  "));
          group.add(b_dig_in);
          group.add(b_single);
          b_dig_in.addActionListener(this);
          b_single.addActionListener(this);
          b_dig_in.setSelected(true);
        }
        
        public void actionPerformed(ActionEvent e) {
          int mode;
          if (b_single == e.getSource()) {
            mode = CheckNode.SINGLE_SELECTION;
          } else {
            mode = CheckNode.DIG_IN_SELECTION;
          }
          for (int i=0;i<nodes.length;i++) {
            nodes[i].setSelectionMode(mode);
          }
        }
      }
      
      class ButtonActionListener implements ActionListener {
        CheckNode root;
        JTextArea textArea;
        
        ButtonActionListener(final CheckNode root,
                             final JTextArea textArea) {
          this.root     = root;
          this.textArea = textArea;
        }
        
        public void actionPerformed(ActionEvent e) {
          Enumeration enum = root.breadthFirstEnumeration();
          while (enum.hasMoreElements()) {
            CheckNode node = (CheckNode)enum.nextElement();
            if (node.isSelected()) {
              TreeNode[] nodes = node.getPath();
              textArea.append("\n" + nodes[0].toString());
              for (int i=1;i<nodes.length;i++) {
                textArea.append("/" + nodes[i].toString());
              }
            }
          }
        }
      }  public static void main(String args[]) {
        CheckNodeTreeExample frame = new CheckNodeTreeExample();
        frame.addWindowListener(new WindowAdapter() {
          public void windowClosing(WindowEvent e) {System.exit(0);}
        });
        frame.setSize(300, 200);
        frame.setVisible(true);
      }
    }
      

  2.   

    /*  swing1.1 */
     
    package jp.gr.java_conf.tame.swing.tree;import java.io.*;
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.tree.*;
    import javax.swing.plaf.ColorUIResource;
    /**
     * @version 1.1 04/24/99
     */
    public class CheckRenderer extends JPanel implements TreeCellRenderer {
      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) {
        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) {
          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));
      }
      
      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;
        }
      }
    }