保存用户在 JavaFX GUI 上创建的节点
Posted
技术标签:
【中文标题】保存用户在 JavaFX GUI 上创建的节点【英文标题】:saving nodes created by user on JavaFX GUI 【发布时间】:2022-01-05 05:58:17 【问题描述】:在此处输入图像描述我在 JavaFX 上制作了一个用于创建时间表的 GUI。当我打开应用程序时,我可以将计划(按钮)添加到日列(VBox)。在我关闭应用程序后,更改不会保存:下次我打开它时,表格是空的。 我的问题是如何让它保存用户创建的节点,以便下次我打开应用程序时它们在那里?
这是添加节点的确切部分:
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
【问题讨论】:
请遵守 java 命名约定 - 至于问题:不要保存节点,而是对状态进行建模并保存模型 【参考方案1】:JavaFX 节点只是数据的表示。他们不应该被拯救。将实际数据本身存储在类的私有字段中。
在您的Application.stop 方法中,将数据写入文件。 在您的 Application.start 方法中,读取该文件并使用它来重建 JavaFX 节点。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);
以上只是一个简化的例子。该文件不必只存储字符串。
我的印象是应用程序中创建的数据比计划字符串更复杂。对于复杂的数据,XML 可能是更合适的文件格式。或者您可以使用 Java 序列化。或者,您可以发明自己的文件格式。
您也不必读取和写入文件。如果您对数据库编程感到满意,您可以使用数据库。或者您可以使用Preferences(尽管首选项不太适合存储复杂数据列表)。
【讨论】:
非常感谢您的回复。这仍然不能解决我的问题。如果我在行中保存简单的东西,比如字符串和数字,那会很容易。即使在这种特殊情况下,我也可以使用一些思维和 SQL 表来做到这一点(我已经看到其中一些在搜索时被使用,但我还没有学习它们)。问题是我正在尝试通过这个来学习,并且在考虑更复杂的结构时,将数据存储为文本或表格并不是一个好的选择。例如,我添加到的 VBox 对于每个按钮都不相同,所以我也必须存储它。 我只是觉得,当我继续更复杂的结构时,如果没有系统的方法来做它会变得太复杂。 如果唯一的解决方案是使用字符串等基本数据对它们进行建模,您能否澄清每个声明的位置?我在这个项目中使用了 FXML、控制器、css 和主文件,所以我知道每个部分的确切位置。 我认为计划所属的父数据对象。但是你没有向我们展示这些,所以我只能根据你展示的内容来回答。写入纯文本文件是最简单的解决方案,但如果您的问题更复杂,则需要更复杂的解决方案。恐怕没有办法解决这个问题。如果不出意外,我希望这个答案说明 VBox 和 Buttons 不是您想要存储的东西;它们的基础数据(即模型)是。 非常感谢 VGR ig 的回答,我正在寻找一种快速解决方案,但当时不存在。非常感谢您阐明这一点并包含该代码,非常感谢【参考方案2】:您应该使用 MVP(模型-视图-演示者)模式。在 UI 层中保存数据不是一个好习惯。使用数据创建模型,然后对其进行序列化。
【讨论】:
ig 那么没有更简单的方法了吗?我认为每次用户添加或删除某物时可能有一种方法可以编辑源文件,例如编辑 FXML。如果没有,那我就按你说的做。以上是关于保存用户在 JavaFX GUI 上创建的节点的主要内容,如果未能解决你的问题,请参考以下文章