JTree的总结

JTree  API:

public class JTree
   
   
    
    extends 
    
    JComponent
   
   
   
   
    
    implements 
    
    Scrollable, 
    
    Accessible
   
   

将分层数据集显示为轮廓的控件。有关面向任务的文档和使用树的示例,请参阅 The Java Tutorial 中的 How to Use Trees 一节。

树中特定的节点可以由 TreePath(封装节点及其所有祖先的对象)标识,或由其显示行(其中显示区域中的每一行都显示一个节点)标识。展开 节点是一个非叶节点(由返回 false 的 TreeModel.isLeaf(node) 标识),当展开 其所有祖先时,该节点将显示其子节点。折叠 节点是隐藏它们的节点。隐藏 节点是位于折叠祖先下面的节点。所有可查看 节点的父节点都是可以展开的,但是可以显示它们,也可以不显示它们。显示 节点是可查看的并且位于可以看到它的显示区域。

以下 JTree 方法使用 "visible" 来表示 "displayed":

  • isRootVisible()
  • setRootVisible()
  • scrollPathToVisible()
  • scrollRowToVisible()
  • getVisibleRowCount()
  • setVisibleRowCount()

下一组 JTree 方法使用 "visible" 表示 "viewable"(在展开的父节点下面):

  • isVisible()
  • makeVisible()

如果您有兴趣了解选择何时更改,请实现 TreeSelectionListener 接口,并使用方法 addTreeSelectionListener 添加实例。当选择更改时,将调用 valueChanged,即如果用户在同一节点上单击两次,则仅调用 valueChanged 一次。

如果有兴趣检测双击事件或用户何时单击节点(不管是否选中它),建议您执行以下操作:

 final JTree tree = ...;

MouseListener ml = new MouseAdapter() {
public void mousePressed(MouseEvent e) {
int selRow = tree.getRowForLocation(e.getX(), e.getY());
TreePath selPath = tree.getPathForLocation(e.getX(), e.getY());
if(selRow != -1) {
if(e.getClickCount() == 1) {
mySingleClick(selRow, selPath);
}
else if(e.getClickCount() == 2) {
myDoubleClick(selRow, selPath);
}
}
}
};
tree.addMouseListener(ml);


想学好JTree必须知道TreeCellRenderer 和 MutableTreeNode的关系
这是学好JTree的关键哦!!!

一颗JTree中,有一个TreeCellRenderer和若干个MutableTreeNode,JTree的节点有多少个,那
MutableTreeNode就有多少个, MutableTreeNode是存放结点的数据的,TreeCellRenderer是读取
MutableTreeNode数据生产节点,所以TreeCellRenderer也是JTree的外观类,如果你想你的JTree变
的有个性,有特点,那就有在TreeCellRenderer设置哦,

例:



[code=Java]import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
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.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.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
/**
* 作者:李 世贵
* JDK: 1.6
* 来源: http://blog.csdn.net/lishigui
* 欢迎转接,请保留作者和来源,谢谢!
* 2009-5-2 上午11:30:46
*/
public class TreeExample extends JFrame {
private static final long serialVersionUID = 1L;
JTree tree;
public TreeExample() {
super("CheckNode TreeExample");
String[] strs = { "我的联系人",
"开发部",
"职能部",
"张三",
"李四",
"王五",
"陈六",
"肖七",
"刘八"};

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[0].add(nodes[2]);
nodes[1].add(nodes[3]);
nodes[1].add(nodes[4]);
nodes[1].add(nodes[5]);
nodes[2].add(nodes[6]);
nodes[2].add(nodes[7]);
nodes[2].add(nodes[8]);
tree = new JTree(nodes[0]);
tree.setCellRenderer(new CheckRenderer());
tree.getSelectionModel().setSelectionMode(
TreeSelectionModel.SINGLE_TREE_SELECTION);
tree.addMouseListener(new NodeSelectionListener(tree));
JScrollPane sp = new JScrollPane(tree);
JPanel panel = new JPanel(new BorderLayout());
getContentPane().add(sp, BorderLayout.CENTER);
getContentPane().add(panel, BorderLayout.EAST);
}

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) {
//取得被单击的节点
CheckNode node = (CheckNode) path.getLastPathComponent();
boolean isSelected = !(node.isSelected());
//设置被单击的节点CheckBox,使其状态与原来状态相反
node.setSelected(isSelected);
//如果节点是被选中,则展开子节点
if (isSelected) {
tree.expandPath(path);
// tree.collapsePath(path);
}
//如果被选节点不是叶节点,将其所有子节点设置为CheckBox状态设成与其相同的状态
if(!node.isLeaf()){
node.getNextNode();
Enumeration enu= node.children();
while (enu.hasMoreElements()) {
CheckNode n = (CheckNode) enu.nextElement();
n.setSelected(node.isSelected());
if(!n.isLeaf()){
Enumeration enuc= n.children();
while (enuc.hasMoreElements()) {
CheckNode c = (CheckNode) enuc.nextElement();
c.setSelected(node.isSelected());
}
}
}
}
//刷新树(这步是必须的,否则将看不到上面所有设置的效果);
((DefaultTreeModel) tree.getModel()).nodeChanged(node);
tree.revalidate();
tree.repaint();
}
}
}

public static void main(String args[]) {
TreeExample frame = new TreeExample();
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 {
//树的节点JPanel编辑,每个节点都是一个JPanel,JPanel中有一个JCheckBox和一个JLabel
//TreeCellRenderer从DefaultMutableTreeNode(即CheckNode)中取得数据设置节点
//TreeCellRenderer主要设置Tree的外观,
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) {
if(((CheckNode) value).getIcon()!=null){
label.setIcon(((CheckNode) value).getIcon());
}else{
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));
}
//布局check和label
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 {
private int selectionMode = 0;
private boolean isSelected = false;
private Icon icon = null;
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;
}

public int getSelectionMode() {
return selectionMode;
}

public void setSelected(boolean isSelected) {
this.isSelected = isSelected;
}

public boolean isSelected() {
return isSelected;
}

public void setIcon(Icon icon){
this.icon = icon;
}

public Icon getIcon(){
return icon;
}
}
[/code]


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值