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节点编辑的练习
xxxxxxxxxxpackage 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(); }
}