简体   繁体   English

Javafx将舞台/场景保存到文件中

[英]Javafx save a stage/scene into a file

I have tried several ways including jaxb and serializing. 我尝试了几种方法,包括jaxb和序列化。 Both didn't really work. 两者都没有真正起作用。 The node s in the stage/scene include Label , BarChart and CodeArea from richTextFX. node在阶段/景S包括LabelBarChartCodeArea从richTextFX。 for the serializing method, i get java.io.NotSerializableException: javafx.scene.chart.BarChart . 对于序列化方法,我得到java.io.NotSerializableException: javafx.scene.chart.BarChart Is there a way to save a scene/stage to a file such as xml (not FXML just saying)? 有没有办法将场景/舞台保存到文件,如xml(不是说FXML)? then, I can restore the scene/stage even if i closed the application. 然后,即使我关闭了应用程序,我也可以恢复场景/阶段。 many thanks. 非常感谢。

As per James_D comment you should save the data from your UI elements not the elements themselves'cos you have them already coded, right?) 根据James_D评论,你应该保存你的UI元素中的数据,而不是你已经编码过的元素本身,对吗?)

A short snippet of the way I did it: 我做的方式的简短片段:

public class SaveRestoreDemo extends Application {

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

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Save/restore demo");
        Group root = new Group();
        Scene scene = new Scene(root, 600, 250, Color.WHITE);

        BorderPane borderPane = new BorderPane();
        borderPane.prefHeightProperty().bind(scene.heightProperty());
        borderPane.prefWidthProperty().bind(scene.widthProperty());

        VBox box = new VBox(10);
        TextArea area = new TextArea();
        area.setId("textArea");

        TextField field = new TextField();
        field.setId("field");

        box.getChildren().addAll(area, field);

        borderPane.setTop(getMainMenuContainer(box.getChildren()));
        borderPane.setCenter(box);
        root.getChildren().add(borderPane);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private VBox getMainMenuContainer(ObservableList<Node> children) {
        VBox topContainer = new VBox();
        MenuBar mainMenu = new MenuBar();
        topContainer.getChildren().add(mainMenu);
        Menu menu = new Menu("Menu");

        MenuItem load = new MenuItem("Load");
        load.setOnAction(e -> load(children));

        MenuItem save = new MenuItem("Save");
        save.setOnAction(e -> save(children));

        menu.getItems().addAll(save, load);

        mainMenu.getMenus().add(menu);
        return topContainer;
    }

    private void load(ObservableList<Node> children) {
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("Load file");
        File file = fileChooser.showOpenDialog(new Stage());
        if (file != null) {
            try {
                Values values = new Gson().fromJson(org.apache.commons.io.FileUtils.readFileToString(file, StandardCharsets.UTF_8), Values.class);
                children.stream().filter(child -> child.getId() != null)
                        .forEach(child -> {
                            if (child instanceof TextField) {
                                TextField field = (TextField) child;
                                field.setText(values.getFieldText());
                            } else if (child instanceof TextArea) {
                                TextArea area = (TextArea) child;
                                area.setText(values.getAreaText());
                            }
                        });
            } catch (IOException e) {
                // handle properly
            }
        }
    }

    private void save(ObservableList<Node> children) {
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("Save file");
        File file = fileChooser.showSaveDialog(new Stage());
        if (file != null) {
            Values values = new Values();
            children.stream().filter(child -> child.getId() != null)
                    .forEach(child -> {
                        if (child instanceof TextField) {
                            TextField field = (TextField) child;
                            values.setFieldText(field.getText());
                        } else if (child instanceof TextArea) {
                            TextArea area = (TextArea) child;
                            values.setAreaText(area.getText());
                        }
                    });

            try {
                org.apache.commons.io.FileUtils.write(file, new Gson().toJson(values), StandardCharsets.UTF_8);
            } catch (IOException e) {
                // handle properly
            }
        }
    }

    private static class Values {
        private String areaText;
        private String fieldText;

        public String getAreaText() {
            return areaText;
        }

        public void setAreaText(String areaText) {
            this.areaText = areaText;
        }

        public void setFieldText(String fieldText) {
            this.fieldText = fieldText;
        }

        public String getFieldText() {

            return fieldText;
        }
    }
}

Basically, I just loop through children of main container, gather values from them and then save to Json using Gson and Apache Commons. 基本上,我只是遍历主容器的子代,从中收集值,然后使用Gson和Apache Commons保存到Json。 This example is very simple, for more complicated saving\\loading you can use id of the nodes. 这个例子非常简单,对于更复杂的save \\ loading,你可以使用节点的id。 For example, you can keep a list or map of ids and then use them as an identifiers while saving and loading. 例如,您可以保留id的列表或映射,然后在保存和加载时将它们用作标识符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM