如何在处理数据时正确更新 JavaFX GUI

我正在尝试进入 JavaFX 以首次尝试使用 Java 制作 GUI。因此,我制作了一个简单的神经网络来学习 XOR 并在 JavaFX 中显示输出。我的问题是 - 如何在处理数据时定期更新 GUI?

到目前为止,我所取得的一切都是网络完成学习后 GUI 中的一次更新。即使我在线程中启动了网络。

我希望 GUI 的右侧更新(圆圈根据输出改变颜色)定期为每个 n 纪元而不是一次。附图显示了网络启动前的 GUI。

http://img3.mukewang.com/647c55000001846805950368.jpg

当年话下
浏览 119回答 1
1回答

湖上湖

JavaFX 有一个“事件线程”,负责处理按钮点击、更新标签和任何其他与 GUI 相关的任务。当您调用时button.setOnAction(e -> doSomething());,当您按下按钮时,doSomething()发生在 JavaFX 线程上。在此运行期间,不会发生其他 GUI 事件。这意味着您的界面将完全冻结,从而导致糟糕的用户体验。此外,您不能在 JavaFX 线程以外的任何线程上执行 GUI 操作,否则您将获得一个IllegalStateException. (试着打电话Executors.newSingleThreadExecutor().execute(() -> label.setText("hello"));看看这个在行动)幸运的是,JavaFX 提供了解决这个问题的方法。首先,也是最简单的方法,是在新线程中调用长时间运行的方法(可能使用ExecutorService上面的 s),当您需要修改接口时,将这些调用包装在对Platform.runLater(() -> updateInterface());. 这将发布updateInterface()到 GUI 线程,并允许它运行。但是,这可能会很麻烦,因此首选方法是使用Service.假设您的长时间运行的计算返回一个Double,您创建一个类 extending Service<Double>,覆盖它的createTask()方法,并在那里执行计算,如下所示:public class CalculationService extends Service<Double> {    @Override    protected Task<Double> createTask() {        return new Task<Double>() {            @Override            protected Double call() throws Exception {                return doCalculation();            }        };    }}然后,在你的控制器中,声明一个private final CalculationService service = new CalculationService();在您的控制器initialize()方法中,您可以将此服务的输出绑定到您想要的任何内容。例如:calculationDisplayLabel.textProperty().bind(Bindings.createStringBinding(service.valueProperty()));// continuously updates the label whenever the service calculates a new value然后,每当您决定要重新开始计算时,service.restart()如果进程正在运行,您可以调用中断进程,并从头开始。如果要在值更改时调用代码,请向服务的值添加一个侦听器。例如,如果您希望它在完成后立即重新计算,请调用:service.valueProperty().addListener((obs, old, newValue) -> service.restart());
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java