簡體   English   中英

Javafx TreeView 目錄列表

[英]Javafx TreeView Directory Listing

我正在嘗試創建一個TreeView來顯示目錄內容,例如:

ABC
    BCD
    123.php

其中 ABC 和 BCD 都是目錄。 我覺得我遺漏了一些東西,因為在我剝離完整目錄位置之前TreeView工作正常,但是一旦我剝離它,它就不會像上面那樣顯示。

public void displayTreeView(String inputDirectoryLocation, CheckBoxTreeItem<String> mainRootItem) {

    // Creates the root item.
    CheckBoxTreeItem<String> rootItem = new CheckBoxTreeItem<>(inputDirectoryLocation);

    // Hides the root item of the tree view.
    treeView.setShowRoot(false);

    // Creates the cell factory.
    treeView.setCellFactory(CheckBoxTreeCell.<String>forTreeView());

    // Get a list of files.
    File fileInputDirectoryLocation = new File(inputDirectoryLocation);
    File fileList[] = fileInputDirectoryLocation.listFiles();

    // Loop through each file and directory in the fileList.
    for (int i = 0; i < fileList.length; i++) {

        // Check if fileList[i] is a file or a directory.
        if (fileList[i].isDirectory()) {

            // Re-iterate through as is directory.
            displayTreeView(fileList[i].toString(), rootItem);

        } else {

            // Check the file type of the file.
            String fileType = Util.retrieveFileType(fileList[i].toString());

            // Check if the file type is the same file type we are searching for. In the future we just add the or symbol to support other file types.
            if (fileType.equals(".php")) {

                // Creates the item.
                CheckBoxTreeItem<String> fileCheckBoxTreeItem = new CheckBoxTreeItem<>(fileList[i].getName());

                // Adds to the treeview.
                rootItem.getChildren().add(fileCheckBoxTreeItem);
            }
        }
    }

    // Check if the mainRootItem has been specified.
    if (mainRootItem == null) {

        // Sets the tree view root item.
        treeView.setRoot(rootItem);
    } else {

        // Creates the root item.
        CheckBoxTreeItem<String> dirCheckBoxTreeItem = new CheckBoxTreeItem<>(fileInputDirectoryLocation.getName());

        // Sets the sub-root item.
        mainRootItem.getChildren().add(dirCheckBoxTreeItem);
    }
}

通過結合TreeView的初始化和構造樹的遞歸方法,您創建了混亂的代碼。

更好地為創建樹創建一個新方法:

public static void createTree(File file, CheckBoxTreeItem<String> parent) {
    if (file.isDirectory()) {
        CheckBoxTreeItem<String> treeItem = new CheckBoxTreeItem<>(file.getName());
        parent.getChildren().add(treeItem);
        for (File f : file.listFiles()) {
            createTree(f, treeItem);
        }
    } else if (".php".equals(Util.retrieveFileType(file.toString()))) {
        parent.getChildren().add(new CheckBoxTreeItem<>(file.getName()));
    }
}

並在您的displayTreeView方法中使用它

public void displayTreeView(String inputDirectoryLocation) {
    // Creates the root item.
    CheckBoxTreeItem<String> rootItem = new CheckBoxTreeItem<>(inputDirectoryLocation);

    // Hides the root item of the tree view.
    treeView.setShowRoot(false);

    // Creates the cell factory.
    treeView.setCellFactory(CheckBoxTreeCell.<String>forTreeView());

    // Get a list of files.
    File fileInputDirectoryLocation = new File(inputDirectoryLocation);
    File fileList[] = fileInputDirectoryLocation.listFiles();

    // create tree
    for (File file : fileList) {
        createTree(file, rootItem);
    }

    treeView.setRoot(rootItem);
}

順便說一句:您的問題是由於創建樹結構並為除根以外的每個節點忽略它引起的(對於非根項目,唯一添加到rootItem節點;對於您添加的除根以外的項目是“平面” dirCheckBoxTreeItem到父取而代之)。

很抱歉提出一個老問題,但我在實施 fabian 的答案時遇到了問題,我認為這可能有用。

瀏覽大目錄(例如根目錄)可能會導致性能問題。 我通過使其僅在TreeItem展開后繼續遞歸來解決它。

private void createTree(File root_file, TreeItem parent) {
    if (root_file.isDirectory()) {
        TreeItem node = new TreeItem(root_file.getName());
        parent.getChildren().add(node);
        for (File f: root_file.listFiles()) {

            TreeItem placeholder = new TreeItem(); // Add TreeItem to make parent expandable even it has no child yet.
            node.getChildren().add(placeholder);

            // When parent is expanded continue the recursive
            node.addEventHandler(TreeItem.branchExpandedEvent(), new EventHandler() {
                @Override
                public void handle(Event event) {
                    createTree(f, node); // Continue the recursive as usual
                    node.getChildren().remove(placeholder); // Remove placeholder
                    node.removeEventHandler(TreeItem.branchExpandedEvent(), this); // Remove event
                }
            });

        }
    } else {
        parent.getChildren().add(new TreeItem(root_file.getName()));
    }
}

除了修改for循環。 我使用TreeItem而不是CheckBoxTreeItem和一些變量名稱,其余相同。


我還遇到了 Windows 文件夾/文件的另一個問題,它是只讀的或受保護的,例如$RECYCLE.BINSystem Volume Information 我通過檢查文件是系統文件還是隱藏或只讀來解決這個問題。 如果是,則忽略該文件/文件夾。

try {
    DosFileAttributes attr = Files.readAttributes(root_file.toPath(), DosFileAttributes.class);
    if(attr.isSystem() || attr.isHidden() || attr.isReadOnly()) {
        // Do nothing
    } else { ... }
} catch (IOException ex) {
    Logger.getLogger(FXMLMainController.class.getName()).log(Level.SEVERE, null, ex);
}

有關檢查文件屬性的更多信息

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM