Search code examples
javauser-interfacejavafxsavenodes

saving nodes created by user on JavaFX GUI


enter image description hereI made a GUI on JavaFX that's for creating timetables. when I open the app I can add plans (Buttons) to day columns (VBox). ofc the changes aren't saved after I close the app: the next time I open it the table is empty. my question is how can I make it save nodes that the user creates so the next time i open the app they're there?

this is the exact part where the nodes get added for what it's worth:

void ask_add_plan(ActionEvent event)
    {
        Button b = (Button) event.getSource();
        VBox v = (VBox) b.getParent();

        AnchorPane pop_up = new AnchorPane(); //this pop up is to specify things about the plan 
                                              //but i removed unnecessary code for simplicity
        
        VBox pop_up_v = new VBox();

        Button add = new Button("Add");
      
        add.setOnAction(e->{
            Button plan = new Button(what_to_do.getText());
           
            v.getChildren().add(plan);

            container.getChildren().remove(pop_up); //container is the anchor pane everything's in
        });

       
        pop_up_v.getChildren().add(add);

        pop_up.getChildren().add(pop_up_v);

        container.getChildren().add(pop_up); //container is the anchor pane everything's in
    }

Solution

  • The JavaFX nodes are just the presentation of your data. They are not meant to be saved. Store the actual data itself in a private field in your class.

    private static final Path PLANS_FILE =
        Path.of(System.getProperty("user.home"), "plans.txt");
    
    private final List<String> plans = new ArrayList<>();
    
    void ask_add_plan(ActionEvent event) {
    
        // ...
    
        add.setOnAction(e -> {
            String planText = what_to_do.getText();
    
            plans.add(planText);
    
            Button plan = new Button(planText);
            v.getChildren().add(plan);
            container.getChildren().remove(pop_up);
        });
    }
    
    @Override
    public void start(Stage primaryStage)
    throws Exception {
    
        // ...
    
        if (Files.exists(PLANS_FILE)) {
            plans.addAll(Files.readAllLines(PLANS_FILE));
    
            // Add UI elements for each stored plan.
            for (String planText : plans) {
                Button planButton = new Button(planText);
                v.getChildren().add(planButton);
                container.getChildren().remove(pop_up);
            }
        }
    }
    
    @Override
    public void stop()
    throws IOException {
        Files.write(PLANS_FILE, plans);
    }
    

    The above is just a simplified example. The file doesn’t have to store just strings.

    I get the impression that the data created in the application is more complex than just plan strings. For complex data, XML may be more a suitable file format. Or you can use Java serialization. Or, you can invent your own file format.

    You also don’t have to read from and write to a file. You can use a database, if you’re comfortable with database programming. Or you can use Preferences (though Preferences are not well suited to storing lists of complex data).