swing树的JTree节点编辑
拖动、编辑树结点: JTree生成的树默认是不可编辑的,不可以添加、删除结点,也不可以改变结点数据 如果想让某个JTree对象变成可编辑状态,则可以调用JTree的setEditable(boolean b)方法,传入true即可把这棵树变成可编辑的树(可以添加、删除结点,也可以改变结点数据)
编辑树结点的步骤:
1、获取当前被选中的结点: 获取当前被选中的结点,会有两种方式。 第一种:通过JTree对象的某些方法,例如TreePath getSelectionPath(),得到一个TreePath对象,包含了从根结点到当前结点路径上的所有结点 第二种:调用TreePath对象的Object getLastPathComponent()方法,得到当前选中结点二,调用JTree对象的Object getLastSelectedPathComponent()方法获取当前被选中的结点 2、调用DefaultTreeModel数据模型有关增删改的一系列方法完成编辑,方法执行完后,会自动重绘JTree
swing树_JTree节点编辑的练习
xxxxxxxxxx
package ch30;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class a_26_swing_树_JTree节点编辑和事件监听 {
JFrame jf = new JFrame("可编辑节点的树");
//定义若干初始结点
DefaultMutableTreeNode root = new DefaultMutableTreeNode("中国");
DefaultMutableTreeNode guangdong = new DefaultMutableTreeNode("广东");
DefaultMutableTreeNode guangxi = new DefaultMutableTreeNode("广西");
DefaultMutableTreeNode foshan = new DefaultMutableTreeNode("佛山");
DefaultMutableTreeNode shantou = new DefaultMutableTreeNode("汕头");
DefaultMutableTreeNode guilin = new DefaultMutableTreeNode("桂林");
DefaultMutableTreeNode nanning = new DefaultMutableTreeNode("南宁");
//定义窗口最底部的四个按钮,完成操作
JButton addSiblingBtn = new JButton("添加兄弟结点");
JButton addChildBtn = new JButton("添加子结点");
JButton deleteBtn = new JButton("删除结点");
JButton editBtn = new JButton("编辑当前结点");
//组装视图
public void init() {
//广东和广西是中国的子节点
root.add(guangdong);
root.add(guangxi);
//佛山和汕头是广东的子节点
guangdong.add(foshan);
guangdong.add(shantou);
//桂林和南宁是广西的子节点
guangxi.add(guilin);
guangxi.add(nanning);
//依据根结点,创建JTree。即中国root是根节点
JTree tree = new JTree(root);
//设置JTree树节点的状态为可编辑
tree.setEditable(true);
//创建JTree关联的数据模型DefaultTreeModel对象,将右边的值强转为DefaultTreeModel类型
DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
//'添加兄弟节点'按钮的事件
addSiblingBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//获取用户选中的结点,下面那行括号里的是强转类型
DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
//如果当前未选中任何节点,就不会添加节点,直接return
if (selectedNode == null) {
return;
}
//获取该选中结点的父结点,下面那行括号里的是强转类型
DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) selectedNode.getParent();
//如果该节点的父结点为空,就不会添加兄弟节点,直接return返回
if (parentNode == null) {
return;
}
//上面那些条件是不能创建节点的条件,如果程序走到这里,就说明当前是可以创建节点的,即可以创建一个新结点
DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("新结点");
//当前选中的这个结点在父节点的哪个索引
int index = parentNode.getIndex(selectedNode);//参数是selectedNode,即当前选中的子节点
//根据拿到的索引,在选中位置插入新结点。参数:新节点、需要添加到哪个父节点里面、在哪个索引处进行添加
model.insertNodeInto(newNode, parentNode, index);
//显示刚刚添加的新结点,即要先获取newNode节点到根节点的路径,返回值是数组,该数组包含了路径上的所有节点
TreeNode[] pathToRoot = model.getPathToRoot(newNode);
//使用指定的结点数组创建TreePath
TreePath treePath = new TreePath(pathToRoot);
//显示指定的treePath,即可显示新节点
tree.scrollPathToVisible(treePath);
//重绘tree UI
tree.updateUI();
};
});
//'添加子节点'按钮的事件
addChildBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//获取用户选中的结点
DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
//如果当前未选中任何节点,就不会添加节点,直接return
if (selectedNode == null) {
return;
}
//创建新结点
DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("新结点");
//索引
//this.model.insertNodeInto(newNode, selectedNode, selectedNode.getChildCount());
//使用TreeModel的方法添加
selectedNode.add(newNode);
//显示刚刚添加的新结点,即要先获取newNode节点到根节点的路径,返回值是数组,该数组包含了路径上的所有节点
TreeNode[] pathToRoot = model.getPathToRoot(newNode);
//使用指定的结点数组创建TreePath
TreePath treePath = new TreePath(pathToRoot);
//显示指定的treePath,即可显示新节点
tree.scrollPathToVisible(treePath);
//重绘tree UI
tree.updateUI();
}
});
//'删除节点'按钮的事件。跟前几个按钮一样的add监听器事件写法,下面剩下的2个按钮就使用Lambda表达式来写,优点:不用重写actionPerformed方法
deleteBtn.addActionListener(e -> {
//下面那行得到的selectedNode就是当前选中的节点
DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
//选中了某个节点 && 当前节点有父节点 。当同时满足这两个条件就可以进行删除
if (selectedNode != null && selectedNode.getParent() != null) {
//从当前选中节点的父节点开始删
model.removeNodeFromParent(selectedNode);
}
});
//'编辑当前节点'按钮的事件。跟前几个按钮一样的add监听器事件写法,下面那行使用Lambda表达式来写
editBtn.addActionListener(e -> {
//获取当前选中节点的路径
TreePath selectionPath = tree.getSelectionPath();
//如果用户选中了某个节点
if (selectionPath != null) {
//用户即可通过该节点的路径来编辑节点
tree.startEditingAtPath(selectionPath);
}
});
//创建一个JPanel对象,用于存放四个按钮
JPanel panel = new JPanel();
//把做好的四个按钮放到一个Panel里面
panel.add(addSiblingBtn);
panel.add(addChildBtn);
panel.add(deleteBtn);
panel.add(editBtn);
//组装视图
jf.add(new JScrollPane(tree));//把树放到整个窗口的中间区域,并给树添加滚动条
jf.add(panel, BorderLayout.SOUTH);//把存放四个按钮的Panel放到整个窗口的南部区域
//设置窗口的最佳大小,设置窗口可见,设置点击叉号就退出程序
jf.pack();
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new a_26_swing_树_JTree节点编辑和事件监听().init();
}
}