Swing之JTree篇:在树节点前增加JCheckBox控件

在做Swing开发的时候可能经常会遇到类似的案例,关键还是需要实现TreeCellRenderer接口,重写getTreeCellRendererComponent方法

 

import java.awt.BorderLayout;   
import java.awt.Color;   
import java.awt.Component;   
import java.awt.Dimension;   
import java.awt.Graphics;   
import java.awt.GridLayout;   
import java.awt.event.ActionEvent;   
import java.awt.event.ActionListener;   
import java.awt.event.MouseAdapter;   
import java.awt.event.MouseEvent;   
import java.awt.event.WindowAdapter;   
import java.awt.event.WindowEvent;   
import java.util.Enumeration;   
  
import javax.swing.ButtonGroup;   
import javax.swing.Icon;   
import javax.swing.JButton;   
import javax.swing.JCheckBox;   
import javax.swing.JFrame;   
import javax.swing.JLabel;   
import javax.swing.JPanel;   
import javax.swing.JRadioButton;   
import javax.swing.JScrollPane;   
import javax.swing.JTextArea;   
import javax.swing.JTree;   
import javax.swing.UIManager;   
import javax.swing.border.TitledBorder;   
import javax.swing.plaf.ColorUIResource;   
import javax.swing.tree.DefaultMutableTreeNode;   
import javax.swing.tree.DefaultTreeModel;   
import javax.swing.tree.TreeCellRenderer;   
import javax.swing.tree.TreeNode;   
import javax.swing.tree.TreePath;   
import javax.swing.tree.TreeSelectionModel;   
  
  
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 ev) {   
      Enumeration e = root.breadthFirstEnumeration();   
      while (e.hasMoreElements()) {   
        CheckNode node = (CheckNode) e.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[]) {   
//    try {   
//        UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");   
//    } catch (Exception evt) {}   
  
    CheckNodeTreeExample frame = new CheckNodeTreeExample();   
    frame.addWindowListener(new WindowAdapter() {   
      public void windowClosing(WindowEvent e) {   
        System.exit(0);   
      }   
    });   
    frame.setSize(300, 200);   
    frame.setVisible(true);   
  }   
}   
  
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;   
    }   
  }   
}   
  
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;   
  }   
}  


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值