User interface 使用JavaFX,如何将GUI组件绑定到数据?

User interface 使用JavaFX,如何将GUI组件绑定到数据?,user-interface,javafx,binding,User Interface,Javafx,Binding,我对JavaFX非常陌生。 我正在开发一个应用程序,在这个应用程序中,我有几个GUI组件,它们根据几个数据值改变外观。例如,可能会显示3个交通灯组件,每个组件都会根据三个不同数据段的设置更改颜色,我们称它们为light1、light2和light3。该组件有一个名为updateColor(int data)的函数,该函数将相应地更新颜色 有一个单独的线程在运行,它定期获取数据值并更新light1、light2和light3中的值 现在,我希望显示的组件在单独的线程更新这些值时自动更改颜色 我读过

我对JavaFX非常陌生。
我正在开发一个应用程序,在这个应用程序中,我有几个GUI组件,它们根据几个数据值改变外观。例如,可能会显示3个交通灯组件,每个组件都会根据三个不同数据段的设置更改颜色,我们称它们为light1、light2和light3。该组件有一个名为updateColor(int data)的函数,该函数将相应地更新颜色

有一个单独的线程在运行,它定期获取数据值并更新light1、light2和light3中的值

现在,我希望显示的组件在单独的线程更新这些值时自动更改颜色


我读过关于绑定的文章,但我所看到的例子似乎都没有解决这种情况。任何关于类似例子的想法或建议都将不胜感激

如果在后台线程中更新这些值,则无法将UI组件的属性绑定到它们,因为这将导致在后台线程中更新UI属性。作为场景图一部分的节点的属性只能在FX应用程序线程上更新

管理这个的一个习惯用法是使用属性注册一个侦听器,并在UI发生更改时从调用
Platform.runLater(…)
更新UI。假设,比如说,
light1
是某种类型
T

light1.addListener((obs, oldValue, newValue) -> 
    Platform.runLater(() -> {
        // update UI with newValue...
    }));
这里的替代方法是让后台线程更新FX应用程序线程上的属性;i、 后台线程调用
Platform.runLater(…)
来更新属性。然后,由于属性仅在FX应用程序线程上进行更改,因此可以安全地将UI属性绑定到它们:

// background thread code:

public void run() {

    // ...

    // periodically update light1 on FX Application Thread:
    Platform.runLater(() -> light1.set(...));

}
然后你就可以做了

someUIElement.someProperty().bind(light1);
(或将
light1
替换为从
light1
派生的一些绑定)


有关将后台服务集成到JavaFX的更一般的策略,请参阅Adam Bien的。

如果在后台线程中更新值,则不能将UI组件的属性绑定到它们,因为这将导致在后台线程中更新UI属性。作为场景图一部分的节点的属性只能在FX应用程序线程上更新

管理这个的一个习惯用法是使用属性注册一个侦听器,并在UI发生更改时从调用
Platform.runLater(…)
更新UI。假设,比如说,
light1
是某种类型
T

light1.addListener((obs, oldValue, newValue) -> 
    Platform.runLater(() -> {
        // update UI with newValue...
    }));
这里的替代方法是让后台线程更新FX应用程序线程上的属性;i、 后台线程调用
Platform.runLater(…)
来更新属性。然后,由于属性仅在FX应用程序线程上进行更改,因此可以安全地将UI属性绑定到它们:

// background thread code:

public void run() {

    // ...

    // periodically update light1 on FX Application Thread:
    Platform.runLater(() -> light1.set(...));

}
然后你就可以做了

someUIElement.someProperty().bind(light1);
(或将
light1
替换为从
light1
派生的一些绑定)


有关将后台服务集成到JavaFX的更多一般策略,请参阅Adam Bien的。

可能重复的可能重复的可能重复的感谢,我将对此进行研究。其中一个问题是后台线程不知道GUI。它的工作只是从外部源获取值并在本地存储。我不确定我是否理解。您说过单独的线程“定期获取数据值并更新light1、light2和light3中的值”。因此,假设您使这些属性可以从外部访问,您只需使用第一个解决方案(
light1.addListener(…)->Platform.runLater(…);
),否?或者你可以使用Adam文章中的回调技术。知道了。谢谢。谢谢,我来看看。其中一个问题是后台线程不知道GUI。它的工作只是从外部源获取值并在本地存储。我不确定我是否理解。您说过单独的线程“定期获取数据值并更新light1、light2和light3中的值”。因此,假设您使这些属性可以从外部访问,您只需使用第一个解决方案(
light1.addListener(…)->Platform.runLater(…);
),否?或者你可以使用Adam文章中的回调技术。知道了。谢谢