我尝试了几种方法,包括jaxb和序列化。两者都没有真正起作用。舞台/场景中的node
包括来自richTextFX的Label
,BarChart
和CodeArea
。对于序列化方法,我得到java.io.NotSerializableException: javafx.scene.chart.BarChart
。有没有办法将场景/舞台保存到文件,如xml(不是说FXML)?然后,即使我关闭了应用程序,我也可以恢复场景/阶段。非常感谢。
答案 0 :(得分:0)
根据 James_D 评论,您应该保存UI元素中的数据而不是元素本身'因为您已经编码了它们,对吗?)
我做的方式的简短片段:
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;
}
}
}
基本上,我只是遍历主容器的子代,从中收集值,然后使用Gson和Apache Commons保存到Json。 这个例子非常简单,对于更复杂的save \ loading,你可以使用节点的id。例如,您可以保留id的列表或映射,然后在保存和加载时将它们用作标识符。