树状结构是一种常用的信息表现形式,它可以直观地显示出一组信息的层次结构。Swing中的JTree类用来创建树,该类的常用构造方法如下表所示:
创建简单的树:
import javax.swing.*;
import javax.swing.tree.*;
import java.util.*;
import java.awt.*;
public class t2 extends JFrame {
public t2() {
setTitle("树操作");
setBounds(400, 400, 400, 400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DefaultMutableTreeNode root = new DefaultMutableTreeNode("根节点");//创建根节点
DefaultMutableTreeNode nodeFirst = new DefaultMutableTreeNode("一级子节点A");//创建一级节点
root.add(nodeFirst);// 将一级节点添加到根节点
DefaultMutableTreeNode nodeSecond = new DefaultMutableTreeNode("二级子节点", false);//创建不允许有子节点的二级节点
nodeFirst.add(nodeSecond);//将二级节点添加到一级节点
root.add(new DefaultMutableTreeNode("一级子节点B"));//创建一级节点
JTree treeRoot = new JTree(root);// 利用根节点直接创建树
add(treeRoot, BorderLayout.WEST);
DefaultTreeModel treeModelDefault = new DefaultTreeModel(root);//利用根节点创建树模型,采用默认的判断方式
JTree treeDefault = new JTree(treeModelDefault);//利用树模型创建树
add(treeDefault, BorderLayout.CENTER);
DefaultTreeModel treeModelPointed = new DefaultTreeModel(root,true);//利用根节点创建树模型,并采用非默认的判断方式
JTree treePointed = new JTree(treeModelPointed);//利用树模型创建树
add(treePointed, BorderLayout.EAST);
setVisible(true);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
t2 T = new t2();
}
}
树的节点选择操作
树的节点允许被选中和取消选中状态,通过捕获树节点的选择事件,可以处理相应的操作。树的选择模式有3种,通过TreeSelectionModel类的对象可以设置树的选择模式。可以通过JTree类的getSelectionModel()方法获得TreeSelectionModel类的对象,然后通过TreeSelectionModel类的setSelectionMode(int mode)方法设置选择模式。该方法的入口参数可以从下表中列出的该类的静态常量中选择。
import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.*;
import java.util.*;
import java.awt.*;
public class t2 extends JFrame {
private static final int DISCONTIGUOUS_TREE_SELECTION = 4;//单选的常量值为1,连选的常量值为2,多选的常量值为4
public t2() {
setTitle("树操作");
setBounds(400, 400, 400, 400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DefaultMutableTreeNode root = new DefaultMutableTreeNode("根节点");
DefaultMutableTreeNode rootFirst = new DefaultMutableTreeNode("一级子节点");
DefaultMutableTreeNode rootSecond = new DefaultMutableTreeNode("二级子节点",false);
root.add(rootFirst);
root.add(rootSecond);
rootFirst.add(new DefaultMutableTreeNode("子节点A",true));
DefaultTreeModel treeModel = new DefaultTreeModel(root);//采用树模型
JTree tree = new JTree(treeModel);
TreeSelectionModel treeSelect;
treeSelect = tree.getSelectionModel();//获得树的选择模式
treeSelect.setSelectionMode(DISCONTIGUOUS_TREE_SELECTION);//设置树的选择模式为多选
tree.addTreeSelectionListener(new TreeSelectionListener() {
@Override
public void valueChanged(TreeSelectionEvent e) {
// TODO Auto-generated method stub
if(!tree.isSelectionEmpty()) {//判断节点是否被选中,被选中为0,没被选中为1
TreePath[] selectionPath =tree.getSelectionPaths();//获取所有被选中节点的路径
for(int i = 0; i < selectionPath.length; i++) {
TreePath path = selectionPath[i];
Object[] obj = path.getPath();//以Object数组的形式返回该路径中所有节点的对象
for(int j = 0; j < obj.length; j++) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) obj[j];// 获得节点
System.out.print(node.getUserObject());
}
System.out.println();
}
}
}
});
add(tree);
setVisible(true);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
t2 T = new t2();
}
}
树的定制
import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.*;
import java.util.*;
import java.awt.*;
public class t2 extends JFrame {
private static final int DISCONTIGUOUS_TREE_SELECTION = 4;//单选的常量值为1,连选的常量值为2,多选的常量值为4
public t2() {
setTitle("树操作");
setBounds(400, 400, 400, 400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DefaultMutableTreeNode root = new DefaultMutableTreeNode("企业人事管理系统");
DefaultMutableTreeNode nodeFirstA = new DefaultMutableTreeNode("人事管理");
nodeFirstA.add(new DefaultMutableTreeNode("账套管理"));
nodeFirstA.add(new DefaultMutableTreeNode("考勤管理"));
nodeFirstA.add(new DefaultMutableTreeNode("奖惩管理"));
nodeFirstA.add(new DefaultMutableTreeNode("培训管理"));
root.add(nodeFirstA);
DefaultMutableTreeNode nodeFirstB = new DefaultMutableTreeNode("待遇管理");
nodeFirstB.add(new DefaultMutableTreeNode("帐套管理"));
nodeFirstB.add(new DefaultMutableTreeNode("人员设置"));
nodeFirstB.add(new DefaultMutableTreeNode("待遇报表"));
root.add(nodeFirstB);
DefaultMutableTreeNode nodeFirstC = new DefaultMutableTreeNode("系统维护");
nodeFirstC.add(new DefaultMutableTreeNode("企业架构"));
nodeFirstC.add(new DefaultMutableTreeNode("基本资料"));
nodeFirstC.add(new DefaultMutableTreeNode("系统初始化"));
root.add(nodeFirstC);
JTree tree = new JTree(root);
tree.setRootVisible(false);//不显示树的根节点
tree.setRowHeight(20);//树节点的行高为20像素
tree.setFont(new Font("宋体", Font.BOLD, 14));//设置树结点的字体
//节点间不采用连接线
tree.putClientProperty("JTree.lineStyle", "None");
DefaultTreeCellRenderer treeCellRenderer;// 获得树节点的绘制对象
treeCellRenderer = (DefaultTreeCellRenderer) tree.getCellRenderer();
treeCellRenderer.setLeafIcon(null);// 设置叶子节点不采用图标
treeCellRenderer.setClosedIcon(null);// 设置节点折叠时不采用图标
treeCellRenderer.setOpenIcon(null);// 设置节点展开时不采用图标
Enumeration<?> enumeration; // 按前序遍历所有树节点
enumeration = root.preorderEnumeration();
while (enumeration.hasMoreElements()) {
DefaultMutableTreeNode node;
node = (DefaultMutableTreeNode) enumeration.nextElement();
if (!node.isLeaf()) {// 判断是否为叶子节点
// 创建该节点的路径
TreePath path = new TreePath(node.getPath());
tree.expandPath(path);// 如果不是则展开该节点
}
}
add(tree);
setVisible(true);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
t2 T = new t2();
}
}
维护树模型:
import java.util.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.tree.*;
public class t3 extends JFrame{
private JPanel panel = new JPanel();
private JScrollPane scrollPane = new JScrollPane();
private JTextField textField = new JTextField();
private JLabel label = new JLabel("名称:");
private JButton addButton = new JButton("添加");
private JButton upButton = new JButton("修改");
private JButton delButton = new JButton("删除");
private DefaultTreeModel treeModel;
private JTree tree;
public t3() {
setTitle("树操作");
setBounds(400, 400, 400, 400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(scrollPane, BorderLayout.WEST);
add(panel, BorderLayout.SOUTH);
DefaultMutableTreeNode root = new DefaultMutableTreeNode("根节点");
DefaultMutableTreeNode rootFirst = new DefaultMutableTreeNode("节点一");
rootFirst.add(new DefaultMutableTreeNode("节点A", true));
rootFirst.add(new DefaultMutableTreeNode("节点B", true));
root.add(rootFirst);
DefaultMutableTreeNode rootSecond = new DefaultMutableTreeNode("节点二");
rootSecond.add(new DefaultMutableTreeNode("节点C", true));
rootSecond.add(new DefaultMutableTreeNode("节点D", true));
root.add(rootSecond);
DefaultMutableTreeNode rootThird = new DefaultMutableTreeNode("节点三");
rootThird.add(new DefaultMutableTreeNode("节点E", true));
rootThird.add(new DefaultMutableTreeNode("节点F", true));
root.add(rootThird);
treeModel = new DefaultTreeModel(root);
tree = new JTree(treeModel);
scrollPane.setViewportView(tree);
panel.add(label);
textField = new JTextField();
textField.setText("请输入……");
textField.setColumns(10);
panel.add(textField);
addButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
DefaultMutableTreeNode node = new DefaultMutableTreeNode(textField.getText());//创建想要添加的节点
TreePath selectionPath = tree.getSelectionPath();//获得选中的父节点路径
DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) selectionPath.getLastPathComponent();//获得选中的父节点
treeModel.insertNodeInto(node, parentNode, parentNode.getChildCount());//插入节点到所有子节点之后
TreePath path = selectionPath.pathByAddingChild(node);// 获得新添加节点的路径
if (!tree.isVisible(path)) {
tree.makeVisible(path);
}
}
});
panel.add(addButton);
upButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// 获得选中的欲修改节点的路径
TreePath selectionPath = tree.getSelectionPath();
DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectionPath.getLastPathComponent();// 获得选中的欲修改节点
node.setUserObject(textField.getText());// 修改节点的用户标签
treeModel.nodeChanged(node);// 通知树模型该节点已经被修改
tree.setSelectionPath(selectionPath);// 选中被修改的节点
}
});
panel.add(upButton);
delButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();// 获得选中的欲删除节点
// 查看欲删除的节点是否为根节点,根节点不允许删除
if (!node.isRoot()) {
DefaultMutableTreeNode nextSelectedNode = node.getNextSibling();// 获得下一个兄弟节点,以备选中
if (nextSelectedNode == null)// 查看是否存在兄弟节点
nextSelectedNode = (DefaultMutableTreeNode) node.getParent();// 如果不存在则选中其父节点
treeModel.removeNodeFromParent(node);// 删除节点
tree.setSelectionPath(new TreePath(nextSelectedNode.getPath()));// 选中节点
}
}
});
panel.add(delButton);
setVisible(true);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
t3 test = new t3();
}
}
处理展开节点事件:
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
public class ExampleFrame_06 extends JFrame {
private static final long serialVersionUID = 1L;
private JTree tree;
public static void main(String args[]) {
ExampleFrame_06 frame = new ExampleFrame_06();
frame.setVisible(true);
}
public ExampleFrame_06() {
super();
setTitle("处理展开节点事件");
setBounds(100, 100, 500, 375);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DefaultMutableTreeNode root = new DefaultMutableTreeNode("倾诚爱家");
DefaultMutableTreeNode nodeA = new DefaultMutableTreeNode("经理办公室");
root.add(nodeA);
DefaultMutableTreeNode nodeB = new DefaultMutableTreeNode("人事部");
root.add(nodeB);
DefaultMutableTreeNode nodeC = new DefaultMutableTreeNode("技术部");
root.add(nodeC);
nodeC.add(new DefaultMutableTreeNode("网络维护部"));
nodeC.add(new DefaultMutableTreeNode("应用开发部"));
DefaultMutableTreeNode nodeD = new DefaultMutableTreeNode("服务部");
root.add(nodeD);
nodeD.add(new DefaultMutableTreeNode("网络服务部"));
nodeD.add(new DefaultMutableTreeNode("内勤开发部"));
DefaultMutableTreeNode nodeE = new DefaultMutableTreeNode("推广部");
root.add(nodeE);
tree = new JTree(root);
// 捕获树节点将要被展开或折叠的事件
tree.addTreeWillExpandListener(new TreeWillExpandListener() {
// 树节点将要被折叠时触发
public void treeWillCollapse(TreeExpansionEvent e) {
TreePath path = e.getPath();// 获得将要被折叠节点的路径
DefaultMutableTreeNode node = (DefaultMutableTreeNode) path
.getLastPathComponent();// 获得将要被折叠的节点
System.out.println("节点“" + node + "”将要被折叠!");
}
// 树节点将要被展开时触发
public void treeWillExpand(TreeExpansionEvent e) {
TreePath path = e.getPath();// 获得将要被展开节点的路径
DefaultMutableTreeNode node = (DefaultMutableTreeNode) path
.getLastPathComponent();// 获得将要被展开的节点
System.out.println("节点“" + node + "”将要被展开!");
}
});
// 捕获树节点已经被展开或折叠的事件
tree.addTreeExpansionListener(new TreeExpansionListener() {
// 树节点已经折叠时触发
public void treeCollapsed(TreeExpansionEvent e) {
TreePath path = e.getPath();// 获得已经被折叠节点的路径
DefaultMutableTreeNode node = (DefaultMutableTreeNode) path
.getLastPathComponent();// 获得已经被折叠的节点
System.out.println("节点“" + node + "”已经被折叠!");
System.out.println();
}
// 树节点已经被展开时触发
public void treeExpanded(TreeExpansionEvent e) {
TreePath path = e.getPath();// 获得已经被展开节点的路径
DefaultMutableTreeNode node = (DefaultMutableTreeNode) path
.getLastPathComponent();// 获得已经被展开的节点
System.out.println("节点“" + node + "”已经被展开!");
System.out.println();
}
});
getContentPane().add(tree, BorderLayout.CENTER);
}
}