T_Ix
T_Ix

Reputation: 66

JavaFX Sorting a TreeView by SubDirectories and Files

I try to sort directories and files in a JavaFX Treeview (using SceneBuilder)

So far im getting a tree in a unsorted way ...

All I want is to have the Root-Item on Top, then get all SubDirectories (not expanded) of the selected Folder and then list all Files.

public void createTreeView(String dbpath) {

    TreeItem<Object> ROOTTREE = new TreeItem<>(dbpath.substring(dbpath.lastIndexOf("\\")));

    try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(Paths.get(dbpath))) {
        for(Path path: directoryStream) {
            if (Files.isDirectory(path)) {
                TreeItem<Object> leafs = new TreeItem<>(strPath.substring(1 + strPath.lastIndexOf("\\")));
                parent.getChildren().add(leafs);
                return leafs;
            } else {
                getLeafs(path, tree);
            }

        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    tree.setExpanded(ROOTTREE);
    TreeView_DBDirectory.setRoot(ROOTTREE);
    TreeView_DBDirectory.setShowRoot(true);
}

I tried to use a Comparator at the createTreeView(), but I#m not sure how to compare TreeItem as Folder and Files.

Maybe there is a more suitable solution? :/

Upvotes: 0

Views: 1739

Answers (1)

jewelsea
jewelsea

Reputation: 159290

Store the directories in an list. Store the files in another list. Add all of the items in directory list to the tree children first. Then add all items of file list to the tree children.

TreeItem<Object> tree = new TreeItem<>(dbPath.substring(dbPath.lastIndexOf(File.separator)));

List<TreeItem<Object>> dirs = new ArrayList<>();
List<TreeItem<Object>> files = new ArrayList<>();

try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(Paths.get(dbPath))) {
    for(Path path: directoryStream) {
        if (Files.isDirectory(path)) {
            TreeItem<Object> subDirectory = new TreeItem<>(path);
            getSubLeafs(path, subDirectory);
            dirs.add(subDirectory);
        } else {
            files.add(getLeafs(path));
        }
    }

    tree.getChildren().addAll(dirs);
    tree.getChildren().addAll(files);
} catch (IOException e) {
    e.printStackTrace();
}

Example running on the following directory structure:

$ tree /tmp/test
/tmp/test
├── a1.txt
├── d1
│   ├── b1.txt
│   └── b2.txt
├── d2
│   └── c1.txt
└── f1.txt

sample

I clicked on the tree nodes to expand them, so you can see their values (by default the tree nodes are not expanded).

Executable Sample

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

import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.util.ArrayList;
import java.util.List;

public class MenuClickSample extends Application {
    TreeView<Object> treeView = new TreeView<>();

    @Override public void start(Stage stage) throws IOException {
        createTreeView("/tmp/test");
        Scene scene = new Scene(treeView);
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

    private void createTreeView(String dbPath) {
        TreeItem<Object> tree = new TreeItem<>(dbPath.substring(dbPath.lastIndexOf(File.separator)));

        List<TreeItem<Object>> dirs = new ArrayList<>();
        List<TreeItem<Object>> files = new ArrayList<>();

        try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(Paths.get(dbPath))) {
            for(Path path: directoryStream) {
                if (Files.isDirectory(path)) {
                    TreeItem<Object> subDirectory = new TreeItem<>(path);
                    getSubLeafs(path, subDirectory);
                    dirs.add(subDirectory);
                } else {
                    files.add(getLeafs(path));
                }
            }

            tree.getChildren().addAll(dirs);
            tree.getChildren().addAll(files);
        } catch (IOException e) {
            e.printStackTrace();
        }

        tree.setExpanded(true);
        treeView.setRoot(tree);
        treeView.setShowRoot(true);
    }

    private TreeItem<Object> getLeafs(Path subPath) {
        String strPath = subPath.toString();
        TreeItem<Object> leafs = new TreeItem<>(strPath.substring(1 + strPath.lastIndexOf(File.separator)));
        return leafs;
    }

    private void getSubLeafs(Path subPath, TreeItem<Object> parent) {
        try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(Paths.get(subPath.toString()))) {
            for(Path subDir: directoryStream) {
                // explicit search for files because we dont want to get sub-sub-directories
                if (!Files.isDirectory(subDir)) {
                    String subTree = subDir.toString();
                    TreeItem<Object> subLeafs = new TreeItem<>(subTree.substring(1 + subTree.lastIndexOf(File.separator)));
                    parent.getChildren().add(subLeafs);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Upvotes: 3

Related Questions