1

I am building an application in Java where I need to represent a predefined directory in any kind of view in my window. Imagine something like a backup application where the main window displays all of the files under a specific directory.

Is there a way to do so using JavaFX? I do not care if files are going to be displayed as a tree or icons or anything really.

Thanks

edit: what I tried so far with no luck. This is my Controller class:

import javafx.scene.control.*;

import java.io.IOException;

public class ViewController {

    public ListView listView;

    public ViewController() throws IOException {
        listView = new ListView();
        listView.getItems().addAll("Iron Man", "Titanic", "Contact", "Surrogates");
    }
}

and my fxml contains:

<ListView fx:id="listView" prefHeight="200.0" prefWidth="200.0" />

Rakim
  • 1,087
  • 9
  • 21
  • 40
  • It's not really clear what your question is. Are you asking if there is a pre-defined file viewer (the answer is no)? If you don't care how they are displayed, then there are many ways to do it (`TreeView` for a tree display, or `ListView` to display a simple list of file names, or `TableView` to display a list of files with some properties, or `TreeTableView` to display a list of files with properties in a hierarchical manner...). The [`TreeItem` documentation](http://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/TreeItem.html) has a partial example of a tree display. – James_D Jan 28 '16 at 19:35
  • i have seen these. But I am wondering if there is an easy way to display a directory without having to start looping through it and creating individual elements for each of its files – Rakim Jan 28 '16 at 19:49
  • 1
    On some level, of course, you have to iterate and create an object for each file. But using either the usual collections API or streams, or similar, it should pretty much be a one-liner to populate e.g. a `ListView`. E.g. `Files.list(directory).forEach(listView.getItems()::add);` (actual code may vary depending on how you have set things up). Your question really isn't specific enough for this forum though: you need to try something and post code with an actual specific programming question if you can get it to work. – James_D Jan 28 '16 at 19:55
  • I tried to be as specific as possible but I am so unfamiliar with UI that I couldn't set it any better. I think your answer just above gives me a hint of how should things be done! Thank you – Rakim Jan 28 '16 at 20:01
  • Check out [my answer](http://stackoverflow.com/questions/34534775/configuring-a-treeview-which-scans-local-fie-system-to-only-include-folders-whic/34540667#34540667), maybe it is what you need. – Roland Jan 28 '16 at 20:09
  • unluckily all of these work when initializing the window. Firstly, I use fxml so the whole initialisation happens in there. Secondly, I want the list to be generated on an event (so within the controller class) which doesn't seem to work. Any ideas? – Rakim Jan 28 '16 at 21:47
  • I recommend you work through some tutorials. [This one](http://code.makery.ch/library/javafx-8-tutorial/) is quite popular. There are several basic errors just in the tiny snippet of code you have posted, and you are not going to learn a whole framework from scratch just by posting on a forum. – James_D Jan 29 '16 at 01:31

1 Answers1

6

I wrote up a brief program that displays a tree of files and directories chosen by the user.

The result:

file chooser window

How it works:

When the user clicks the "Load Folder" button, getNodesForDirectory is called, and recursively walks through the file tree, making tree items along the way.

Here is the code:

import java.io.File;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.BorderPane;
import javafx.stage.DirectoryChooser;
import javafx.stage.Stage;

public class DirectoryViewer extends Application {

    @Override
    public void start(Stage primaryStage) {
        TreeView<String> a = new TreeView<String>();
        BorderPane b = new BorderPane();
        Button c = new Button("Load Folder");
        c.setOnAction(new EventHandler<ActionEvent>() {
            @Override public void handle(ActionEvent e) {
                DirectoryChooser dc = new DirectoryChooser();
                dc.setInitialDirectory(new File(System.getProperty("user.home")));
                File choice = dc.showDialog(primaryStage);
                if(choice == null || ! choice.isDirectory()) {
                    Alert alert = new Alert(AlertType.ERROR);
                    alert.setHeaderText("Could not open directory");
                    alert.setContentText("The file is invalid.");

                    alert.showAndWait();
                } else {
                    a.setRoot(getNodesForDirectory(choice));
                }
            }
        });
        b.setTop(c);
        b.setCenter(a);
        primaryStage.setScene(new Scene(b, 600, 400));
        primaryStage.setTitle("Folder View");
        primaryStage.show();
    }

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

    public TreeItem<String> getNodesForDirectory(File directory) { //Returns a TreeItem representation of the specified directory
        TreeItem<String> root = new TreeItem<String>(directory.getName());
        for(File f : directory.listFiles()) {
            System.out.println("Loading " + f.getName());
            if(f.isDirectory()) { //Then we call the function recursively
                root.getChildren().add(getNodesForDirectory(f));
            } else {
                root.getChildren().add(new TreeItem<String>(f.getName()));
            }
        }
        return root;
    }
}

Good luck with your project!

halfer
  • 19,824
  • 17
  • 99
  • 186
  • I know how to do that in the main class. My problem is that I cannot do it within the controller class – Rakim Jan 31 '16 at 15:25
  • @Rakim Why can't you do it from the controller class? Sorry if I didn't understand the question. – InternetUnexplorer Jan 31 '16 at 16:40
  • I am accepting anyway. but what I was doing was trying to add the `TreeView` that I was creating through the controller. But nothing was showing on my UI although the list had items. So the solution was to pass the Parent of the fxml in my controller from what I found. However, this is just what I came up with and I am sure there are more solutions to that and maybe better than mine – Rakim Jan 31 '16 at 17:01