Java 将扫描本地文件系统的TreeView配置为仅包含具有文件类型的文件夹

Java 将扫描本地文件系统的TreeView配置为仅包含具有文件类型的文件夹,java,file,javafx,treeview,observablelist,Java,File,Javafx,Treeview,Observablelist,好的,我使用了这个网站的第二段代码 其中声明“以下代码从本地文件系统创建动态树” 我不明白该代码是如何根据我的需要进行定制的。特别是覆盖方法,似乎没有一个地方可以添加“仅将文件夹添加到包含mp3文件的子目录”。我认为这可能需要一些更复杂的东西,比如一些能够浏览和删除文件夹的东西。我真的不确定 我曾尝试在我的程序中使用此代码来显示mp3文件。其想法是让两个TreeView并排显示,左侧显示文件夹的层次结构,其中包含mp3文件的文件夹(不显示其他没有mp3文件的文件夹),右侧显示这些文件夹中仅包含m

好的,我使用了这个网站的第二段代码 其中声明“以下代码从本地文件系统创建动态树”

我不明白该代码是如何根据我的需要进行定制的。特别是覆盖方法,似乎没有一个地方可以添加“仅将文件夹添加到包含mp3文件的子目录”。我认为这可能需要一些更复杂的东西,比如一些能够浏览和删除文件夹的东西。我真的不确定

我曾尝试在我的程序中使用此代码来显示mp3文件。其想法是让两个TreeView并排显示,左侧显示文件夹的层次结构,其中包含mp3文件的文件夹(不显示其他没有mp3文件的文件夹),右侧显示这些文件夹中仅包含mp3文件类型的文件。下面有一个屏幕截图

这是我到目前为止所用的代码,它在VBox中返回一个树视图。 有两段代码被注释掉了。第一个原因是不希望搜索我的C:驱动器。(我不知道为什么)。所以我把它改为只扫描我的D:(分区驱动器)。第二个是从我得到主要代码段的网页。这段代码被移动到一个处理。以及处理多个驱动器的厚脸皮代码

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.VBox;
import org.apache.commons.io.FileUtils;

/**
 * https://stackoverflow.com/questions/6251762/java-search-file-according-to-its-name-in-directory-and-subdirectories
 * https://stackoverflow.com/questions/26690247/how-to-make-directories-expandable-in-javafx-treeview
 * http://www.java2s.com/Tutorials/Java/JavaFX/0660__JavaFX_Tree_View.htm
 *
 * @author Scorchgid
 */
public class FolderTreeView {

    int x = 0;
    private final String fileName = ".mp3";
    private MainView mainView;
    private TreeView<File> treeViewFile = new TreeView<>();

    public TreeView<File> getTreeViewFile() {
        return treeViewFile;
    }

    public void setTreeViewFile(TreeView<File> treeViewFile) {
        this.treeViewFile = treeViewFile;
    }

    public VBox treeStack() throws IOException {
        VBox vbox = new VBox();
        File[] drives = File.listRoots();
        ArrayList<File> fileListing;
        /*for (File dir : drives) {
            System.out.println(dir.toString());
            fileListing = restrictingList(dir);
        }*/
        fileListing = restrictingList(new File("D:\\"));

        ArrayList<TreeItem> treeItems = new ArrayList<>();
        for (File dir : drives) {
            //System.out.println(dir.toString());
            treeItems.add(createNode(dir));
        }
        TreeView<File> tree = proxyCreateNode(treeItems);
        vbox.getChildren().add(tree);

        return vbox;
    }

    // https://stackoverflow.com/questions/22260032/set-two-root-nodes-for-treeview
    public TreeView<File> proxyCreateNode(ArrayList<TreeItem> arrayListTreeItem) {
        TreeItem<File> proxyItem = new TreeItem<>();
        proxyItem.setExpanded(true);
        for (TreeItem<File> item : arrayListTreeItem) {
            proxyItem.getChildren().addAll(item);
        }
        TreeView<File> tree = new TreeView<>(proxyItem);
        tree.setShowRoot(false);
        return tree;
    }

    private ArrayList<File> restrictingList(File root) {
        ArrayList<File> fileArray = new ArrayList<>();        
        boolean recursive = true;        
        Collection files = FileUtils.listFiles(root, null, recursive);
        for (Iterator iterator = files.iterator(); iterator.hasNext();) {
            File file = (File) iterator.next();
            if (file.getName().endsWith(fileName)) {
                fileArray.add(file);              
            }
        }
        return fileArray;
    }

    /*    @Override
     public void start(Stage stage) {
     Scene scene = new Scene(new Group(), 300, 300);

     TreeItem<File> root = createNode(new File("c:/"));
     TreeView treeView = new TreeView<File>(root);

     vbox.getChildren().add(treeView);
     ((Group) scene.getRoot()).getChildren().add(vbox);

     stage.setScene(scene);
     stage.show();
     }
     */
    private TreeItem<File> createNode(final File f) {
        return new TreeItem<File>(f) {
            private boolean isLeaf;
            private boolean isFirstTimeChildren = true;
            private boolean isFirstTimeLeaf = true;

            @Override
            public ObservableList<TreeItem<File>> getChildren() {
                if (isFirstTimeChildren) {
                    isFirstTimeChildren = false;
                    super.getChildren().setAll(buildChildren(this));
                }
                return super.getChildren();
            }

            @Override
            public boolean isLeaf() {
                if (isFirstTimeLeaf) {
                    isFirstTimeLeaf = false;
                    File f = (File) getValue();
                    isLeaf = f.isFile();
                }
                return isLeaf;
            }

            private ObservableList<TreeItem<File>> buildChildren(
                    TreeItem<File> TreeItem) {
                File f = TreeItem.getValue();
                if (f == null) {
                    return FXCollections.emptyObservableList();
                }
                if (f.isFile()) {
                    return FXCollections.emptyObservableList();
                }
                File[] files = f.listFiles();
                if (files != null) {
                    ObservableList<TreeItem<File>> children = FXCollections
                            .observableArrayList();
                    for (File childFile : files) {
                        //System.out.println("Adding " + childFile.getAbsolutePath());
                        if (childFile.isDirectory()) {
                            children.add(createNode(childFile));
                        }
                    }
                    return children;
                }
                return FXCollections.emptyObservableList();
            }
        };
    }
}
导入java.io.File;
导入java.io.IOException;
导入java.util.ArrayList;
导入java.util.Collection;
导入java.util.Iterator;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.scene.control.TreeItem;
导入javafx.scene.control.TreeView;
导入javafx.scene.layout.VBox;
导入org.apache.commons.io.FileUtils;
/**
* https://stackoverflow.com/questions/6251762/java-search-file-according-to-its-name-in-directory-and-subdirectories
* https://stackoverflow.com/questions/26690247/how-to-make-directories-expandable-in-javafx-treeview
* http://www.java2s.com/Tutorials/Java/JavaFX/0660__JavaFX_Tree_View.htm
*
*@author Scorchgid
*/
公共类FolderTreeView{
int x=0;
私有最终字符串fileName=“.mp3”;
私有主视图主视图;
private TreeView treeViewFile=new TreeView();
公共树视图getTreeViewFile(){
返回treeViewFile;
}
公共无效setTreeView文件(TreeView TreeView文件){
this.treeViewFile=treeViewFile;
}
public VBox treeStack()引发IOException{
VBox VBox=新的VBox();
File[]驱动器=File.listRoots();
ArrayList文件列表;
/*用于(文件目录:驱动器){
System.out.println(dir.toString());
fileListing=限制列表(dir);
}*/
fileListing=限制列表(新文件(“D:\\”);
ArrayList treeItems=新的ArrayList();
用于(文件目录:驱动器){
//System.out.println(dir.toString());
add(createNode(dir));
}
TreeView树=proxyCreateNode(treeItems);
vbox.getChildren().add(树);
返回vbox;
}
// https://stackoverflow.com/questions/22260032/set-two-root-nodes-for-treeview
公共树视图proxyCreateNode(ArrayList arrayListTreeItem){
TreeItem proxyItem=新的TreeItem();
proxyItem.setExpanded(true);
对于(TreeItem项:arrayListTreeItem){
proxyItem.getChildren().addAll(项目);
}
TreeView树=新的TreeView(proxyItem);
tree.setShowRoot(false);
回归树;
}
私有ArrayList限制列表(文件根){
ArrayList fileArray=新的ArrayList();
布尔递归=真;
集合文件=FileUtils.listFiles(根、空、递归);
for(Iterator Iterator=files.Iterator();Iterator.hasNext();){
File=(File)iterator.next();
if(file.getName().endsWith(文件名)){
添加(文件);
}
}
返回文件数组;
}
/*@覆盖
公众假期开始(阶段){
场景=新场景(新组(),300,300);
TreeItem root=createNode(新文件(“c:/”));
TreeView TreeView=新的TreeView(根);
vbox.getChildren().add(treeView);
((组)scene.getRoot()).getChildren().add(vbox);
舞台场景;
stage.show();
}
*/
私有树Item createNode(最终文件f){
返回新树项(f){
私有布尔isLeaf;
私有布尔值isFirstTimeChildren=true;
私有布尔值isFirstTimeLeaf=true;
@凌驾
公共观察列表getChildren(){
如果(isFirstTimeChildren){
isFirstTimeChildren=false;
super.getChildren().setAll(buildChildren(this));
}
返回super.getChildren();
}
@凌驾
公共布尔isLeaf(){
如果(isFirstTimeLeaf){
isFirstTimeLeaf=false;
文件f=(文件)getValue();
isLeaf=f.isFile();
}
返回岛;
}
私人观察者儿童(
TreeItem TreeItem){
文件f=TreeItem.getValue();
如果(f==null){
返回FXCollections.emptyObservableList();
}
if(f.isFile()){
返回FXCollections.emptyObservableList();
}
File[]files=f.listFiles();
如果(文件!=null){
ObservableList children=FXCollections
.observableArrayList();
用于(文件子文件:文件){
//系统
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Comparator;
import java.util.function.Function;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class FolderTreeView extends Application {

    private static final String ROOT_FOLDER = "c:/music"; // TODO: change or make selectable

    @Override
    public void start(Stage primaryStage) throws IOException {

        // create root
        TreeItem<Path> treeItem = new TreeItem<Path>(Paths.get( ROOT_FOLDER));
        treeItem.setExpanded(true);

        // create tree structure
        createTree( treeItem);

        // sort tree structure by name
        treeItem.getChildren().sort( Comparator.comparing( new Function<TreeItem<Path>, String>() {
            @Override
            public String apply(TreeItem<Path> t) {
                return t.getValue().toString().toLowerCase();
            }
        }));

        // create components
        TreeView<Path> treeView = new TreeView<Path>(treeItem);
        StackPane root = new StackPane();
        root.getChildren().add(treeView);
        primaryStage.setScene(new Scene(root, 1024, 768));
        primaryStage.setTitle("Folder Tree View Example");
        primaryStage.show();

    }

    /**
     * Recursively create the tree
     * @param rootItem
     * @throws IOException
     */
    public static void createTree(TreeItem<Path> rootItem) throws IOException {

        try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(rootItem.getValue())) {

            for (Path path : directoryStream) {

                TreeItem<Path> newItem = new TreeItem<Path>(path);
                newItem.setExpanded(true);

                rootItem.getChildren().add(newItem);

                if (Files.isDirectory(path)) {
                    createTree(newItem);
                }
            }
        }
    }


    public static void main(String[] args) {
        launch(args);
    }
}
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Comparator;
import java.util.function.Function;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class FolderTreeViewWithFilter extends Application {

    private static final String ROOT_FOLDER = "c:/music"; // TODO: change or make selectable

    TreeItem<FilePath> rootTreeItem;
    TreeView<FilePath> treeView;

    @Override
    public void start(Stage primaryStage) throws IOException {

        // root component
        VBox root = new VBox();

        // filter
        TextField filter = new TextField();
        filter.textProperty().addListener((observable, oldValue, newValue) -> filterChanged(newValue));

        // treeview
        treeView = new TreeView<FilePath>();
        VBox.setVgrow(treeView, Priority.ALWAYS);

        root.getChildren().addAll( filter, treeView);

        // stage
        primaryStage.setScene(new Scene(root, 1024, 768));
        primaryStage.setTitle("Folder Tree View With Filter Example");
        primaryStage.show();

        // create tree
        createTree();

        // show tree structure in tree view
        treeView.setRoot(rootTreeItem);
    }

    /**
     * Create original tree structure
     * @throws IOException
     */
    private void createTree() throws IOException {

        // create root
        rootTreeItem = createTreeRoot();

        // create tree structure recursively
        createTree( rootTreeItem);

        // sort tree structure by name
        rootTreeItem.getChildren().sort( Comparator.comparing( new Function<TreeItem<FilePath>, String>() {
            @Override
            public String apply(TreeItem<FilePath> t) {
                return t.getValue().toString().toLowerCase();
            }
        }));

    }

    /**
     * Iterate through the directory structure and create a file tree
     * @param rootItem
     * @throws IOException
     */
    public static void createTree(TreeItem<FilePath> rootItem) throws IOException {

        try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(rootItem.getValue().getPath())) {

            for (Path path : directoryStream) {

                TreeItem<FilePath> newItem = new TreeItem<FilePath>( new FilePath( path));
                newItem.setExpanded(true);

                rootItem.getChildren().add(newItem);

                if (Files.isDirectory(path)) {
                    createTree(newItem);
                }
            }
        }
        // catch exceptions, e. g. java.nio.file.AccessDeniedException: c:\System Volume Information, c:\$RECYCLE.BIN
        catch( Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Create new filtered tree structure
     * @param root
     * @param filter
     * @param filteredRoot
     */
    private void filter(TreeItem<FilePath> root, String filter, TreeItem<FilePath> filteredRoot) {

        for (TreeItem<FilePath> child : root.getChildren()) {

            TreeItem<FilePath> filteredChild = new TreeItem<>( child.getValue());
            filteredChild.setExpanded(true);

            filter(child, filter, filteredChild );

            if (!filteredChild.getChildren().isEmpty() || isMatch(filteredChild.getValue(), filter)) {
                filteredRoot.getChildren().add(filteredChild);
            }

        }
    }

    /**
     * Comparator for tree filter
     * @param value
     * @param filter
     * @return
     */
    private boolean isMatch(FilePath value, String filter) {
        return value.toString().toLowerCase().contains( filter.toLowerCase()); // TODO: optimize or change (check file extension, etc)
    }

    /**
     * Show original tree or filtered tree depending on filter
     * @param filter
     */
    private void filterChanged(String filter) {
        if (filter.isEmpty()) {
            treeView.setRoot(rootTreeItem);
        }
        else {
            TreeItem<FilePath> filteredRoot = createTreeRoot();
            filter(rootTreeItem, filter, filteredRoot);
            treeView.setRoot(filteredRoot);
        }
    }

    /**
     * Create root node. Used for the original tree and the filtered tree.
     * Another option would be to clone the root.
     * @return
     */
    private TreeItem<FilePath> createTreeRoot() {
        TreeItem<FilePath> root = new TreeItem<FilePath>( new FilePath( Paths.get( ROOT_FOLDER)));
        root.setExpanded(true);
        return root;
    }

    /**
     * Wrapper for the path with overwritte toString method. We only want to see the last path part as tree node, not the entire path.
     */
    private static class FilePath {

        Path path;
        String text;

        public FilePath( Path path) {

            this.path = path;

            // display text: the last path part
            // consider root, e. g. c:\
            if( path.getNameCount() == 0) {
                this.text = path.toString();
            }
            // consider folder structure
            else {
                this.text = path.getName( path.getNameCount() - 1).toString();
            }

        }

        public Path getPath() {
            return path;
        }

        public String toString() {

            // hint: if you'd like to see the entire path, use this:
            // return path.toString();

            // show only last path part
            return text;

        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}
/**
 * Create new filtered tree structure
 * @param root
 * @param filter
 * @param filteredRoot
 */
private void filter(TreeItem<FilePath> root, String filter, TreeItem<FilePath> filteredRoot) {

    for (TreeItem<FilePath> child : root.getChildren()) {

        TreeItem<FilePath> filteredChild = new TreeItem<>( child.getValue());
        filteredChild.setExpanded(true);

        filter(child, filter, filteredChild );

        boolean hasItem = false;
        for (TreeItem<FilePath> subChild: child.getChildren()) {
            if( isMatch( subChild.getValue(), filter)) {
                hasItem = true;
                break;
            }
        }

        if (!filteredChild.getChildren().isEmpty() || hasItem) {
            filteredRoot.getChildren().add(filteredChild);
        }

    }
}