一、文件拖拽相关API的实现:
1.1 DnD的实现(DropTargetListener)
public class JTreeDnD extends JTree implements DropTargetListener {}
@SuppressWarnings("unchecked")
@Override
public void drop(DropTargetDropEvent dtde) {
DataFlavor dataFlavor = DataFlavor.javaFileListFlavor;
if (dtde.isDataFlavorSupported(dataFlavor)) {
dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
List<File> list = null;
Transferable transferable = dtde.getTransferable();
try {
list = (List<File>) transferable.getTransferData(dataFlavor);
} catch (UnsupportedFlavorException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
addNewUserObjects((DefaultMutableTreeNode) this.getModel().getRoot(), list);
dtde.dropComplete(true);
}
}
二、文件树相关API的实现:
2.1 JTree
jTreeDnD = new JTreeDnD();
jTreeDnD.setShowsRootHandles(true);
jTreeDnD.setDragEnabled(true);
jTreeDnD.setEditable(true);
2.2 DefaultMutableTreeNode
DefaultMutableTreeNode dmTreeNodeRoot = new DefaultMutableTreeNode();
dmTreeNodeRoot.setUserObject("图层");
2.3 DefaultTreeModel
DefaultTreeModel treeModelRoot = new DefaultTreeModel(dmTreeNodeRoot);
jTreeDnD.setModel(treeModelRoot);
三、子节点的增删,拖拽
3.1 文件读取
private void loadResources(File[] fileArray) {
jTreeDnD.addNewUserObjects((DefaultMutableTreeNode) ((DefaultTreeModel) jTreeDnD.getModel()).getRoot(),
fileUtils.toList(fileArray));
}
前面第一部分有介绍,拖拽使用了list<File>来读取文件,此处沿用了以上方法。
3.2 添加子节点
DefaultTreeModel dtm = (DefaultTreeModel) this.getModel();
for (Iterator<File> iterator = list.iterator(); iterator.hasNext();) {
File file = (File) iterator.next();
DefaultMutableTreeNode dmtn = new DefaultMutableTreeNode();
if (file.isDirectory()) {
dmtn.setAllowsChildren(true);
} else {
dmtn.setAllowsChildren(false);
}
dmtn.setUserObject(file);
dtm.insertNodeInto(dmtn, parent, 0);
}
MutableTreeNode提供的方法:
public void insertNodeInto(MutableTreeNode newChild, MutableTreeNode parent, int index){}
3.3 文件夹展开
如以上代码片段,对于文件夹须有展开的操作,所以调用了setAllowsChildren(true)方法。
private void expandDirectory(int selRow, TreePath selPath) {
DefaultMutableTreeNode treeNodeSelected = (DefaultMutableTreeNode) selPath.getLastPathComponent();
if (null == treeNodeSelected) {
return;
}
Object object = treeNodeSelected.getUserObject();
if (object instanceof File) {
File file = (File) object;
if (file.isDirectory()) {
jTreeDnD.addNewUserObjects(treeNodeSelected, fileUtils.toList(file.listFiles()));
}
}
}
关于选择节点的获取,用上了TreePath,官方API文档介绍了一个监听器:
MouseListener ml = new MouseAdapter() {
public void mousePressed(MouseEvent e) {
int selRow = jTreeDnD.getRowForLocation(e.getX(), e.getY());
TreePath selPath = jTreeDnD.getPathForLocation(e.getX(), e.getY());
if (selRow != -1) {
if (e.getClickCount() == 1) {
mySingleClick(selRow, selPath);
} else if (e.getClickCount() == 2) {
myDoubleClick(selRow, selPath);
}
}
}
};
jTreeDnD.addMouseListener(ml);
TreePath selPath = jTreeDnD.getPathForLocation(e.getX(), e.getY());
获取当前选择的节点:
DefaultMutableTreeNode treeNodeSelected = (DefaultMutableTreeNode) selPath.getLastPathComponent();
3.4 删除节点
3.5 拖拽节点
抱歉,以上的不会,还有更多的JTree可执行操作,个人还没学到手学到脑学进DNA。。。T_T
强调:个人经验不足,看了好多大佬写的文章后,以为自己懂了实际上啥都没懂。实际写上一段代码快把自己气哭。关于JTree相关的一系列操作,很多大佬推荐使用DefaultTreeModel来操作节点(节点修改后实时更新显示),本人经历了几天的头痛才整理出相对可行的方法,以上关于JTree的文章等待有机会补全。
之前做了个基于ImageIO的Java小工具,集合了图层合并切片分割等功能的小工具。这段时间无聊想整个文件拖拽,类似可编辑图层的升级版本小工具,考虑了许久就盯上了JTree的相关信息。这次把项目源码发到GitHub了,方便交流学习和及时修改代码。
以下为项目效果图
完整代码发到GitHub仓库了,想看可以点击下面链接跳转阅读。
项目地址:GitHub - neverever1533/EvolutionVector: 一些个人用的图形化小工具