-1

I'd like to create a tree view that displays a mod folder (the root directory) and the mods inside, but not the mod folders contents. Right now I can only get it to display all of the mod levels but I think its my method BuildChildren(). Any help would be appreciated.

I've included the code below.

import java.io.File;
import javafx.scene.control.TreeView;
import javafx.scene.control.TreeItem;
import javafx.scene.Node;



    public class SimpleFileTreeItem extends TreeItem<File> {

    public SimpleFileTreeItem(File f) {
        super(f);
    }
 
    @Override
    public ObservableList<TreeItem<File>> getChildren() {
        if (isFirstTimeChildren) {
                        isRoot = true;
            isFirstTimeChildren = false;
 
            /*
             * First getChildren() call, so we actually go off and determine the
             * children of the File contained in this TreeItem.
             */
            super.getChildren().setAll(buildChildren(this));
        }
        return super.getChildren();
    }

    public boolean isBranch() {
        if (isLeaf == false && isRoot == false) {
                        isRoot = false;
            isFirstTimeLeaf = true;
            File f = (File) getValue();
            isBranch = f.isFile();
        }
 
        return isBranch;
    }


    public boolean isLeaf() {
        if (isBranch == false && isRoot == false) {
                        isRoot = false;
            isFirstTimeLeaf = true;
            File f = (File) getValue();
            isLeaf = f.isFile();
        }
 
        return isLeaf;
    }

    public boolean isLeafTip() {
        if (isBranch == false && isRoot == false) {
                        isRoot = false;
            isFirstTimeLeaf = false;
            File f = (File) getValue();
            isLeafTip = f.isFile();
        }
 
        return isLeafTip;
    }

    private ObservableList<TreeItem<File>> buildChildren(TreeItem<File> TreeItem) {
        File f = TreeItem.getValue();
        if (f != null && f.isDirectory()) {
                        isRoot = true;
            File[] files = f.listFiles();
            if (files != null && isLeaf == false && isRoot == true) {
                ObservableList<TreeItem<File>> childFile = FXCollections.observableArrayList();
                                isBranch = true;
 
                                if(isBranch == true && isFirstTimeLeaf == false) {   
                                
                for (File file : files) {
                    childFile.add(new SimpleFileTreeItem(file));
                }
                                    return childFile;
                                }
                        }
                }    
        return FXCollections.emptyObservableList();
    }
 
    private boolean isFirstTimeChildren = true;
    private boolean isRoot = true;
    private boolean isFirstTimeLeaf = false;
    private boolean isLeaf = false;
        private boolean isBranch = false;
        private boolean isLeafTip;
}

}

Any help would be greatly appreciated. I think its the buildChildren method for sure, as that for each loop is just sort of building as it goes. I don't know what would be a better way to do this though. Cheers.

TedDraws
  • 13
  • 1
  • 2
  • 2
    Perhaps simplify this for yourself to see if you can write a plain Java program (no UI) that [recurses the filesystem](https://docs.oracle.com/javase/tutorial/essential/io/walk.html) to output the filtered locations to the console. – jewelsea Feb 24 '22 at 23:35
  • 1
    For [example](https://stackoverflow.com/a/2009376/230513). – trashgod Feb 24 '22 at 23:49
  • 1
    “a mod folder (the root directory) and the mods inside, but not the mod folders contents” -> I can’t understand this statement at all. What is a mod folder and mods in this context? What does it mean to not display the mod folders contents? – jewelsea Feb 25 '22 at 01:21
  • @jewelsea I guess i mean just the mod folder names and the folder that holds the mods. The content would be like textures, xml files, etc and the info.xml file with the mods metadata. I don't want the viewer to be able to see that since I'm building a mod loader. I think your original suggestion is best though jewelsea, ill try that out. – TedDraws Feb 25 '22 at 03:10
  • 2
    this looks similar to the broken example in TreeView (in an incorrect override of isLeaf) - beware that this may lead to trouble! See https://bugs.openjdk.java.net/browse/JDK-8089811 and related issues – kleopatra Feb 25 '22 at 11:29

1 Answers1

0

I have done it this way. You may modify it according to your needs:

private void createTreeView(String dirPath) {
    TreeItem<Object> tree = new TreeItem<>(dirPath.substring(dirPath.lastIndexOf(File.separator) + 1), new ImageView(icon));
    List<TreeItem<Object>> dirs = new ArrayList<>();
    try {
        DirectoryStream<Path> directoryStream = Files.newDirectoryStream(Paths.get(dirPath));
        for (Path path : directoryStream) {
            if (Files.isDirectory(path)) {
                String pathString = path.toString();
                TreeItem<Object> subDirectory = new TreeItem<>(pathString.substring(pathString.lastIndexOf(File.separator) + 1), new ImageView(icon));
                getSubLeafs(path, subDirectory);
                dirs.add(subDirectory);
            }
        }

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

    treeView.getSelectionModel().selectedItemProperty().addListener((obs, oldVal, newVal) -> {
        imageNumber = 1;
        StringBuilder pathBuilder = new StringBuilder();
        for (TreeItem<String> item = (TreeItem<String>) treeView.getSelectionModel().getSelectedItem(); item != null; item = item.getParent()) {

            pathBuilder.insert(0, item.getValue());
            pathBuilder.insert(0, "/");
        }
        String path = pathBuilder.toString();
        populateImageView(path.substring(1) + "/");
    });

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

private void getSubLeafs(Path subPath, TreeItem<Object> parent) {
    try {
        DirectoryStream<Path> directoryStream = Files.newDirectoryStream(Paths.get(subPath.toString()));
        for (Path subDir : directoryStream) {
            if (Files.isDirectory(subDir)) {
                String subTree = subDir.toString();
                TreeItem<Object> subLeafs = new TreeItem<>(subTree, new ImageView(icon));
                subLeafs.setValue(subTree.substring(subTree.lastIndexOf(File.separator) + 1));
                getSubLeafs(subDir, subLeafs);
                parent.getChildren().add(subLeafs);
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}
Rafa
  • 467
  • 4
  • 18