动态创建树知识点
案例要点:
1,给按钮添加监听器
2,getLastSelectedPathComponent():获取用户在树形组件上选择的那个对象,但是该对象是被当作object对象类型返回的,所以对其返回值进行强制类型转换为节点类型
3, TreeSelectionListener():用来监听用户选择节点的操作,一旦用户选择了某个节点,监听器会立刻捕获到用户的动作,知道用户选择的哪一个节点,从而计算出从根节点到被选中节点的唯一路径
4,为一颗树添加新节点的核心代码,
- 获取被选中的节点
- 从文本框获取新节点名称
- 添加新节点到被选中的节点
5,每次新增节点,都要为新增节点选中父节点,父节点是唯一的,要求树形组件是单选模式,
6,把重复语句封装成方法,我们在设计方法的时候,要把方法所涉及的工作,要从逻辑上,划分边界,不要设计一个大而全的方法,要小而专,功能明确
7,所有操作,都可以再添加一个确认
案例:
代码:
package Tree.mugejiangtang;
import java.awt.Container;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
/**
* 参考链接:
*
* 给按钮添加监听器
* getLastSelectedPathComponent
* 获取用户在树形组件上选择的那个对象,但是该对象是被当作object对象类型返回的,所以对其返回值进行强制类型转换
* TreeSelectionListener
* 监听用户选择节点的操作
* 一旦用户选择了某个节点,监听器会立刻捕获到用户的动作
* 知道用户选择的哪一个节点,从而计算出从根节点到被选中节点的唯一路径
*
*/
public class NewFrame11 extends JFrame{
JTree familyTree;
JScrollPane jspFamily;
JTree dynTree;
JScrollPane jspDyn;
DefaultMutableTreeNode treeRoot ,temp; //temp 引用指向被选中节点
JTextField txtName;
JButton btnAdd,btnRename,btnDelete;
TreePath path; //用来表示节点路径
public NewFrame11(){
init();
}
private void init( ){
Container container = this.getContentPane();//获得窗体的主体区域
container.setLayout(null);
treeRoot = new DefaultMutableTreeNode("根");
dynTree = new JTree(treeRoot);
jspDyn = new JScrollPane(dynTree);
txtName = new JTextField();
btnAdd = new JButton("新增");
btnRename = new JButton("修改");
btnDelete = new JButton("删除");
dynTree.setFont(new Font("微软雅黑", Font.PLAIN, 18));
//每次新增节点,都要为新增节点选中父节点,父节点是唯一的,要求树形组件是单选模式,
dynTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
dynTree.addTreeSelectionListener(new TreeSelectionListener() {
@Override
public void valueChanged(TreeSelectionEvent e) { //一旦用户选择节点变化,立即执行
path = e.getPath();
}
});
jspDyn.setSize(350, 250);
jspDyn.setLocation(400, 30);
txtName.setSize(80, 30);
txtName.setLocation(400, 300);
txtName.setFont(new Font("微软雅黑", Font.PLAIN, 18));
btnAdd.setSize(80, 30);
btnAdd.setLocation(490, 300);
btnAdd.setFont(new Font("微软雅黑", Font.PLAIN, 18));
//给按钮添加监听器
btnAdd.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//被选中的节点,把新节点添加到他下面
temp = (DefaultMutableTreeNode)dynTree.getLastSelectedPathComponent();
//新节点名称
String name = txtName.getText();
if(validate(temp,name)==true){
//添加新节点
temp.add(new DefaultMutableTreeNode(name));
//想要展示节点,就要把该节点从根节点一直到该节点,全部展现出来
dynTree.expandPath(path);
//给树组件添加新节点后,不会立刻显示,需要刷新一下,才显示
dynTree.updateUI();
}
}
});
btnRename.setSize(80, 30);
btnRename.setLocation(580, 300);
btnRename.setFont(new Font("微软雅黑", Font.PLAIN, 18));
btnRename.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
temp = (DefaultMutableTreeNode)dynTree.getLastSelectedPathComponent();
String name = txtName.getText();
if(validate(temp,name)==true){
//对树组件进行重命名的方法
temp.setUserObject(name);
dynTree.updateUI();
}
}
});
btnDelete.setSize(80, 30);
btnDelete.setLocation(670, 300);
btnDelete.setFont(new Font("微软雅黑", Font.PLAIN, 18));
btnDelete.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
temp = (DefaultMutableTreeNode)dynTree.getLastSelectedPathComponent();
if(temp==null){
System.out.println("请选中一个节点!");
return;
}
if(temp.isRoot()==true){
System.out.println("不能删除根节点!");
return;
}
temp.removeFromParent();
dynTree.updateUI();
}
});
DefaultMutableTreeNode root = new DefaultMutableTreeNode("曹操");
DefaultMutableTreeNode a1 = new DefaultMutableTreeNode("曹昂");
DefaultMutableTreeNode a2 = new DefaultMutableTreeNode("曹丕");
DefaultMutableTreeNode a3 = new DefaultMutableTreeNode("曹植");
DefaultMutableTreeNode a4 = new DefaultMutableTreeNode("曹彰");
root.add(a1);
root.add(a2);
root.add(a3);
root.add(a4);
DefaultMutableTreeNode b1 = new DefaultMutableTreeNode("曹睿");
DefaultMutableTreeNode b2 = new DefaultMutableTreeNode("曹霖");
DefaultMutableTreeNode b3 = new DefaultMutableTreeNode("曹志");
a2.add(b1);
a2.add(b2);
a3.add(b3);
DefaultMutableTreeNode c1 = new DefaultMutableTreeNode("曹芳");
b1.add(c1);
familyTree = new JTree(root);
familyTree.setFont(new Font("微软雅黑", Font.PLAIN, 18));
jspFamily = new JScrollPane(familyTree);
jspFamily.setSize(300, 250);
jspFamily.setLocation(30, 30);
container.add(jspFamily);
container.add(jspDyn);
container.add(txtName);
container.add(btnAdd);
container.add(btnRename);
container.add(btnDelete);
}
//编程,一定要防止大量重复性代码的出现,把相同代码提炼成方法
boolean validate(DefaultMutableTreeNode node,String name){
if(node==null){
System.out.println("请选择一个节点!");
return false;
}
name = txtName.getText();
if(name.equals("")){
System.out.println("请填写节点的名称");
return false;
}
return true;
}
}
测试代码:
package Tree.mugejiangtang;
import javax.swing.JFrame;
public class Test {
public static void main(String[] args) {
NewFrame11 myFrame = new NewFrame11();
myFrame.setSize(800, 400);
myFrame.setLocationRelativeTo(null);
myFrame.setTitle("窗体标题");
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setVisible(true);
}
}
自学了解:
参考链接:
https://www.bilibili.com/video/BV1JB4y1u7sM?p=35