以前转过一篇英文文档讲解Tree_with_checkbox,讲的比较深,代码改造起来比较麻烦。但如果需要在一般的程序中使用带CheckBox的JTree,那么使用以下代码基本上够用了

可用代码如下:
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 p_w_picpathOffset = 0;
      Icon currentI = getIcon();
      if (currentI != null) {
        p_w_picpathOffset = currentI.getIconWidth()
          + Math.max(0, getIconTextGap() - 1);
      }
      g.fillRect(p_w_picpathOffset, 0, d.width - 1 - p_w_picpathOffset,
              d.height);
      if (hasFocus) {
        g.setColor(UIManager
              .getColor("Tree.selectionBorderColor"));
        g.drawRect(p_w_picpathOffset, 0, d.width - 1 - p_w_picpathOffset,
              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 {

public final static int SINGLE_SELECTION = 0;

public final static int DIG_IN_SELECTION = 4;

protected int selectionMode;

protected boolean isSelected;

protected boolean expanded;

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 e = children.elements();
    while (e.hasMoreElements()) {
    CheckNode node = (CheckNode) e.nextElement();
    node.setSelected(isSelected);
    }
  }
}

public void setExpanded(boolean isExpanded) {
  this.expanded = isExpanded;

  if ( (selectionMode == DIG_IN_SELECTION) && (children != null)) {
    Enumeration e = children.elements();
    while (e.hasMoreElements()) {
    CheckNode node = (CheckNode) e.nextElement();
    node.setExpanded(isExpanded);
    }
  }
}

public boolean isExpanded() {
  return expanded;
}

public boolean isSelected() {
  return isSelected;
}
}


生成一颗节点为CheckNode的树,并setCellRenderer(new CheckRenderer());