使用JTree增加,删除,和重命名节点完整实例
首先来看一下效果,如下图所示,该目录结构树,通过在右键Pop菜单实现了添加子目录,删除目录和重命名目录的功能,当然在双击目录节点的时候也可以完成重命名的操作下面就来看一下怎样具体实现吧,关于拖拽部分已经在http://blog.csdn.net/luoshenfu001/article/details/10893673上面有完整的实现了,在此就不再累述,本文只关注树节点的增,删和重命名的实现,下面使用将整个JTree放入JScrollPanel中,然后JScrollPanle又在一个大的JPanel中。
简单的说,实现增加和删除并不太难,可以使用DefaultTreeModel的两个基本方法:treeModel.insertNodeInto(childNode, parent, parent.getChildCount()); 和treeModel.removeNodeFromParent(currentNode); 就可以了,在注意添加的时候确保UserObject (就是放在TreeNode里面的对象)为真正的用户数据对象就可以了。
对于重命名节点的实现可谓费了很多周折,实现Oralce官方文档中‘How to use a tree’中的方法,给TreeModel添加treeModel监听器来监听TreeNode值的改变,但是在里面得到的UserObject的类型竟然变为了String,丧失了原来的自定义对象类型,非常奇怪!后来终于在StackoverFlow中找到了解决方案,那就是实现自定义的TreeModel,并修改的valueForPathChanged方法的实现,就大功告成了。
http://stackoverflow.com/questions/11554583/jtree-node-rename-preserve-user-object
看来还是外国人给力啊。
另外,还值得一提的是,不论是通过双击重命名还是右键重命名都可以使用下面这一小段来实现重命名的效果!岂不是很赞?
if (evt.getClickCount() == 2) {
TreePath path = tree.getSelectionPath();
tree.startEditingAtPath(path);
}
本文代码中依赖的几个其他类都在上面的链接中有,想要的可以去上一篇中寻找。
package test;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import org.apache.log4j.Logger;
public class TreePanel extends JPanel {
private final Logger logger = Logger.getLogger(TreePanel.class);
private static final long serialVersionUID = 1975901083214104961L;
private JTree tree;
private InnerDocsMgt mainPanel;
private List<VEachDir> dirsList = new ArrayList<VEachDir>();
private DefaultTreeModel treeModel;
private DefaultMutableTreeNode rootNode;
private Toolkit toolkit = Toolkit.getDefaultToolkit();
public TreePanel(InnerDocsMgt mainPanel) {
super();
this.mainPanel = mainPanel;
init();
}
public void init() {
GridBagLayout gbl_panel = new GridBagLayout();
gbl_panel.columnWidths = new int[] { 54, 0, 0, 0, 0, 0, 0, 0 };
gbl_panel.rowHeights = new int[] { 31, 0, 0 };
gbl_panel.columnWeights = new double[] { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, Double.MIN_VALUE };
gbl_panel.rowWeights = new double[] { 0.0, 1.0, Double.MIN_VALUE };
this.setLayout(gbl_panel);
JLabel lblNewLabel = new JLabel(
"\u5185\u90E8\u8D44\u6599\u76EE\u5F55\u5217\u8868");
GridBagConstraints gbc_lblNewLabel = new GridBagConstraints();
gbc_lblNewLabel.gridwidth = 5;
gbc_lblNewLabel.insets = new Insets(0, 0, 5, 5);
gbc_lblNewLabel.gridx = 0;
gbc_lblNewLabel.gridy = 0;
add(lblNewLabel, gbc_lblNewLabel);
JButton saveDirsOprBt = new JButton(
"\u4FDD\u5B58\u76EE\u5F55\u64CD\u4F5C");
GridBagConstraints gbc_saveDirsOprBt = new GridBagConstraints();
gbc_saveDirsOprBt.insets = new Insets(0, 0, 5, 5);
gbc_saveDirsOprBt.gridx = 5;
gbc_saveDirsOprBt.gridy = 0;
add(saveDirsOprBt, gbc_saveDirsOprBt);
saveDirsOprBt.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String title = "注意!";
String message = "是否确定保存对目录的修改!";
int messageType = JOptionPane.INFORMATION_MESSAGE;
int result = JOptionPane.showConfirmDialog(mainPanel, message,
title, JOptionPane.YES_NO_OPTION, messageType);
if (result == JOptionPane.YES_OPTION) {
System.out.println("Yes");
logger.debug("用户确定了对目录的修改!");
DocsMgtRmi.getINS().saveDirChanged(dirsList);
}
}
});
JScrollPane scrollPane = new JScrollPane();
GridBagConstraints gbc_scrollPane = new GridBagConstraints();
gbc_scrollPane.gridwidth = 7;
gbc_scrollPane.fill = GridBagConstraints.BOTH;
gbc_scrollPane.gridx = 0;
gbc_scrollPane.gridy = 1;
add(scrollPane, gbc_scrollPane);
VEachDir rootDir = new VEachDir(0, "/", 0, 123);
rootNode = new DefaultMutableTreeNode(rootDir);
createNodes(rootNode);
treeModel = new DocTreeModel(rootNode);
treeModel.addTreeModelListener(new DocTreeModelListener());
tree = new JTree(treeModel);
tree.getSelectionModel().setSelectionMode(
TreeSelectionModel.SINGLE_TREE_SELECTION);
scrollPane.setViewportView(tree);
tree.setEditable(true);
tree.setDragEnabled(true);
tree.setTransferHandler(new DocsTreeTransferHanlder(dirsList));
setPopupMenu();
}
private void createNodes(DefaultMutableTreeNode top) {
List<DefaultMutableTreeNode> nodes = DocsMgtRmi.getINS()
.getFirstLevelDirs();
for (DefaultMutableTreeNode one : nodes) {
top.add(one);
}
}
public DefaultMutableTreeNode getSelectedNode() {
return (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
}
public void setPopupMenu() {
final JPopupMenu pop = new JPopupMenu();
pop.add(new AbstractAction("添加子目录") {
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
System.out.println("Tree Add");
VEachDir newDir = new VEachDir(0, "新的目录", 0, 123);
DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(
newDir);
addObject(newDir);
}
});
pop.add(new AbstractAction("删除目录") {
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
System.out.println("Delete");
removeCurrentNode();
}
});
pop.add(new AbstractAction("重命名&qu补充:软件开发 , Java ,
上一个:关于全屏和取消标题栏
下一个:Java简单工厂模式
- 更多JAVA疑问解答:
- java怎么在线读取ftp服务器上的文件内容
- 关于程序员的职业规划
- HTML和JSP矛盾吗?
- java小程序如何打包?
- java怎么split路径文件名?
- 关于Hibernate实体自身多对一的抓取问题
- 关于apache2+tomcat群集出现的问题
- SSH 导入导出excel 谁有这块的资料吗?
- springmvc 加载一个jsp页面执行多个方法 报404
- 关于用jquery 导入 excel
- java对时间进行循环放到List中
- 一个图片的输入输出程序,第一次调用某方法会中断,第二次调用则正常
- 请上过传智播客的人说一下传智播客怎么样呀!是不是像它说的那样好呀!
- spring的schema怎么配置
- 【菜鸟求助】SSH中怎么从JSP页面往后台传值呢