在 Java 中使用 WatchService 或 JNotify 时,文件树组件不会动态更新自身

问题描述 投票:0回答:0

我的项目使用了一个自定义文件树组件,它显示来自任何操作系统根节点的文件信息。当我选择一个项目时,文件名、文件路径、文件类型显示在 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 组件,我不确定哪里出错了。尽管我尽了最大的努力,但我无法让它发挥作用。我不确定我还能做什么!感谢您的帮助!

java swing jtree watchservice
© www.soinside.com 2019 - 2024. All rights reserved.