-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.

5
  • 2
    Perhaps simplify this for yourself to see if you can write a plain Java program (no UI) that recurses the filesystem to output the filtered locations to the console. Commented Feb 24, 2022 at 23:35
  • 1
    For example. Commented Feb 24, 2022 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? Commented Feb 25, 2022 at 1: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. Commented Feb 25, 2022 at 3: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 bugs.openjdk.java.net/browse/JDK-8089811 and related issues Commented Feb 25, 2022 at 11:29

1 Answer 1

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();
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.