在java中,树对象提供了用树型结构分层显示数据的视图。可以扩展和收缩视图中的单个子树。树由Swing中的JTree类实现,JTree是Jcomponent的子类。其构造函数如下所示:
JTree(HashTable ht) //散列表中的每个元素是树的一个子节点
JTree(Object obj[]) //对象数组obj中的每一个元素都是树的子节点
JTree(TreeNode tn) //树节点tn是树的跟节点
JTree(Vector v) //向量V中的元素是树的子节点
树的数据模型是TreeModel,是由许多TreeNode对象组成。选择树中节点的方法是由TreeSelectionModel定义的,可以选择TreePath。TreeCellRenderer定义树中每个元素如何显示。JTree的所有支持类都在javax.swing.tree包中。
TreeModel接口定义树的基础数据结构
包括如下方法:
addTreeModelListener(TreeModelListener l)
removeTreeModelListener(TreeModelListener l)
public Object getRoot()
public Object getChild(Object parent, int index)
public int getChildCount(Object parent)
public Boolean isLeaf(Object node)
public void valueForPathChanged(TreePath path,Object newValue)
public int getIndexOfChild(Object parent, Object child)
和其它组件一样,有个缺省版本,DefaultTreeModel,负责在数据模型改变时通知听众。
要找出树模型什么时候改变,就要注册TreeModelListener,这样就可以在树结构改变时得到TreeModelEvent.
当节点扩展或收缩时,JTree对象生成事件
void addTreeExpansionListener(TreeExpansionListener tel)
void removeTreeExpansionListener(TreeExpansionListener tel)
其中,tel是监听器对象
TreeNode接口定义了获取树节点信息的方法。例如:它能够得到关于父节点的引用,或者一个子节点的枚举。MutableTreeNode接口扩展了TreeNode接口。它定义了插入和删除子节点或者改变父节点的方法。DefaultMutableTreeNode类实现了MutableTreeNode接口。它代表树中的一个节点。其构造函数如下所示:
DefaultMutableTreeNode(Object obj)
要创建树节点的层次结构,需使用DefaultMutableTreeNode的add()方法。其使用方式:
void add(MutableTreeNode child)
其中child是一个可变的树节点,被当作当前节点的子节点插入。
树的扩展事件由javax.swing.event包中的TreeExpansionEvent类描述。这个类的getPath()方法返回一个TreePath对象
TreeExpansionListener接口提供下列的两个方法:
Void treeCollapsed(TreeExpansionEvent tee)
Void treeExpanded(TreeExpansionEvent tee)
其中,tee是树的扩展事件。当一个子树隐藏时,调用第一个方法。当一个子树变为可见时,调用第二个方法。
TreeCellRenderer用于定制显示树的每个单元。定制显示时,通常要用Jlabel并根据树的节点值和当前设置配置图标和文本。
public Component getTreeCellRendererComponent(JTree tree, Object value,
Boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus)
这个方法返回一个Component这个控件,也就是你要设置的树中节点的显示风格,当然在实现的时候你可以继承一个Jcomponent类的子类,也可以在类中设置一个私有变量然后返回。在这个方法中有很多参数:
Jtree //这个就是你要设置的树对应的对象,
Value //这个其实是节点,通过他你可以获得节点的数据,以及对应的子节点父节点等。
Selected //表示如果被选中时该如何显示。
Expanded //表示如果出于扩展状态如何显示节点
Leaf //叶子节点的显示方式可以通过这个条件设置
Row //对于那些没有伸缩的可以,如果有伸缩的话,row是随时改变的所以用的时候要小心
HasFocus //是是否拥有焦点,设置拥有焦点时的显示方式。
实现了这个方法后,用setCellRenderer()方法设置一下这个类的实例就行了。
为了使应用程序对节点选择事件做出响应,你需要首先注册一个选择监听器。在这之前你还要首选指定树选择模型TreeSelectionModel,它有三个参数:
CONTIGUOUS_TREE_SELECTION:这是默认值,可以选择不同节点的任意组合
SINGLE_TREE_SELECTION:每次只能选择一个节点
DISCONTIGUOUS_TREE_SELECTION:只能选择相邻的一组节点。
tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
// Listen for when the selection changes
tree.addTreeSelectionListener(new TreeSelectionListener(){
public void valueChanged(TreeSelectionEvent e){
DefaultMutableTreeNode node=(DefaultMutableTreeNode)tree.getLastSelectedPathComponent();
if(node==null)
return;
Object nodeinfo=node.getUserObject();
System.out.println("leaf: "+nodeinfo.toString());
}
});
例子:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
public class JTreeEvents{
class MyCellRenderer extends JLabel implements TreeCellRenderer{
MyCellRenderer(){
setOpaque(true);
}
public Component getTreeCellRendererComponent(JTree tree,
Object value,boolean selected,boolean expanded,boolean leaf,
int row,boolean hasFocus){
StringBuffer text=new StringBuffer();
if(expanded)
text.append("E:");
if(leaf)
text.append("L:");
if(hasFocus)
text.append("H:");
text.append(row+"->");
text.append(value.toString());
setBackground(selected ? Color.blue:Color.yellow);
setForeground(selected ? Color.yellow : Color.blue);
setText(text.toString());
return this;
}
}
public JTreeEvents(){
JFrame f=new JFrame("Trees");
DefaultMutableTreeNode top=new DefaultMutableTreeNode("Options");
// Create subtree of "A"
DefaultMutableTreeNode a=new DefaultMutableTreeNode("A");
top.add(a);
DefaultMutableTreeNode a1=new DefaultMutableTreeNode("A1");
a.add(a1);
DefaultMutableTreeNode a2=new DefaultMutableTreeNode("A2");
a.add(a2);
// Create subtree of "B"
DefaultMutableTreeNode b=new DefaultMutableTreeNode("B");
top.add(b);
DefaultMutableTreeNode b1=new DefaultMutableTreeNode("B1");
b.add(b1);
DefaultMutableTreeNode b2=new DefaultMutableTreeNode("B2");
b.add(b2);
DefaultMutableTreeNode b3=new DefaultMutableTreeNode("B3");
b.add(b3);
// Create subtree of Months
DefaultMutableTreeNode months=new DefaultMutableTreeNode("Months");
top.add(months);
String monthLabels[]={"January","February","March","April","May","June"};
for(int i=0,n=monthLabels.length;i<n;i++){
months.add(new DefaultMutableTreeNode(monthLabels[i]));
}
// Create tree
JTree tree=new JTree(top);
tree.setCellRenderer(new MyCellRenderer());
// Add tree to a scroll pane
int v=ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED;
int h=ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED;
JScrollPane jsp=new JScrollPane(tree,v,h);
// Add scroll pane to the content pane
// Get content pane
Container contentPane=f.getContentPane();
// Create top node of tree
contentPane.add(jsp,BorderLayout.CENTER);
// Anonymous inner class to handle mouse clicks
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
f.setSize(250,250);
f.show();
}
public static void main(String args[])
{
new JTreeEvents();
}
}