带选择框的JTree

CheckNode.java

import java.util.Enumeration;
import javax.swing.tree.DefaultMutableTreeNode;

/**
 * ChcekNodeTree树的结点
 * @version 1.1 01/15/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 e = children.elements();
   while (e.hasMoreElements()) {
    CheckNode node = (CheckNode) e.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); } }
  */

}

CheckNodeTree.java

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;
import javax.swing.tree.TreeModel;

/**
 * 带Chcek的JTree示例
 * @version 1.1 01/15/99
 */
public class CheckNodeTree extends JTree {

 public CheckNodeTree() {
  this(new DefaultTreeModel(null));
 }

 public CheckNodeTree(TreeModel model) {
  super(model);

  setCellRenderer(new CheckRenderer());
  getSelectionModel().setSelectionMode(
    TreeSelectionModel.SINGLE_TREE_SELECTION
  );
  addMouseListener(new NodeSelectionListener(this));
 }

 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) {
    DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
    if (node instanceof CheckNode) {
     CheckNode chNode = (CheckNode) node;
     boolean isSelected = ! (chNode.isSelected());
     chNode.setSelected(isSelected);
     if (chNode.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();
       }
    }
   }
  }
 }

 public static void main(String args[]) {
  String[] strs = {"swing",     // 0
    "platf",     // 1
    "basic",     // 2
    "metal",     // 3
  "JTree"};    // 4

  CheckNode[] nodes = new CheckNode[strs.length];
  DefaultMutableTreeNode root = new DefaultMutableTreeNode("root");
  for (int i=0;i<strs.length;i++) {
   nodes[i] = new CheckNode(strs[i]);
  }
  root.add(nodes[0]);
  nodes[0].add(nodes[1]);
  nodes[1].add(nodes[2]);
  nodes[1].add(nodes[3]);
  nodes[0].add(nodes[4]);
  DefaultTreeModel model = new DefaultTreeModel(root);
  CheckNodeTree tree = new CheckNodeTree(model);
  JFrame frame = new JFrame("测试");
  frame.addWindowListener(new WindowAdapter() {
   public void windowClosing(WindowEvent e) {
    System.exit(0);
   }
  });
  JScrollPane jsp = new JScrollPane(tree);
  frame.getContentPane().setLayout(new BorderLayout());
  frame.getContentPane().add(jsp, BorderLayout.CENTER);
  frame.setSize(300, 200);
  frame.setVisible(true);
 }
}

class CheckRenderer extends JPanel implements TreeCellRenderer {
 protected JCheckBox check;

 protected TreeLabel label;
 DefaultTreeCellRenderer dtcr = new DefaultTreeCellRenderer();
 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) {
  if (!(value instanceof CheckNode)) {
   return dtcr.getTreeCellRendererComponent(tree, value, isSelected, expanded, leaf, row, 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;
  }
 }
}

效果图

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值