我的项目使用了一个自定义文件树组件,它显示来自任何操作系统根节点的文件信息。当我选择一个项目时,文件名、文件路径、文件类型显示在 JTable 中。我需要修复 fileTree 组件的一个问题,即如何在发生文件事件(例如文件创建、删除、移动或重命名)时动态更新 fileTree。
这是 FileTree.java 文件,其中包含用于访问特定操作系统和 WatchService 函数的根目录的 initRoot() 方法。
private void initRoot() {
File[] roots = null;
if (Constants.isWindows) {
roots = fsv.getRoots();
} else if (Constants.isLinux || Constants.isOSX) {
roots = new File[]{new File(System.getProperty("user.home"))};
} else {
roots = File.listRoots();
}
if (roots.length == 1) {
rootNode = new DefaultMutableTreeNode(new FileTreeNode(roots[0]));
populateSubTree(rootNode);
} else if (roots.length > 1) {
rootNode = new DefaultMutableTreeNode("Computer");
for (File root : roots) {
rootNode.add(new DefaultMutableTreeNode(root));
}
} else {
rootNode = new DefaultMutableTreeNode("Error");
}
fileTreeModel.setRoot(rootNode);
}
WatchService 代码具有 startFileWatcher()、updateFileTree()、addChildren() 函数即
public void startFileWatcher() {
try {
File file= null;
// Get the file system
FileSystem fs = file.toPath().getFileSystem();
// Create a new watch service
WatchService service = fs.newWatchService();
// Register the file to be watched for changes
file.toPath().register(service, StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY);
// Start the infinite loop that will check for file system changes
while (true) {
WatchKey key = service.take();
// Process each event in the watch key
for (WatchEvent<?> event : key.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();
// Handle file create event
if (kind == StandardWatchEventKinds.ENTRY_CREATE) {
// Update the file tree
updateFileTree();
}
// Handle file delete event
else if (kind == StandardWatchEventKinds.ENTRY_DELETE) {
// Update the file tree
updateFileTree();
}
// Handle file modify event
else if (kind == StandardWatchEventKinds.ENTRY_MODIFY) {
// Update the file tree
updateFileTree();
}
}
// Reset the watch key
boolean valid = key.reset();
if (!valid) {
break;
}
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
public void updateFileTree() {
// Get the current root node
DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode) getModel().getRoot();
// Clear the children of the root node
rootNode.removeAllChildren();
File file = null;
// Add the children of the file to the root node
addChildren(file, rootNode);
// Update the tree
((DefaultTreeModel) getModel()).reload();
// Expand the root node to show any newly added child nodes
expandRow(0);
}
public void addChildren(File file, DefaultMutableTreeNode parent) {
// Get the files and directories in the current directory
File[] files = file.listFiles();
// Sort the files and directories alphabetically
Arrays.sort(files);
// Add each file and directory to the parent node
for (File child : files) {
DefaultMutableTreeNode node = new DefaultMutableTreeNode(new FileTreeNode(child));
parent.add(node);
if (child.isDirectory()) {
addChildren(child, node);
}
}
}
为了定期刷新文件树组件,我在 initRoot() 函数中实现了一个定时器功能,然而,这是以额外的 CPU 使用率和资源占用为代价的。当我将 println 语句放入 WatchService 代码中时,输出中没有打印任何内容。我的主项目使用了JNotify,当我调用updateFileTree()或initRoot()函数时,它们被调用了,但是File Tree组件不能动态更新!以前从未使用过 JTree 组件,我不确定哪里出错了。尽管我尽了最大的努力,但我无法让它发挥作用。我不确定我还能做什么!感谢您的帮助!