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

时间:2016-10-04 13:20:53

标签: user-interface javafx binding

我是JavaFX的新手 我正在开发一个应用程序,我有几个GUI组件,它们根据几个数据值改变外观。例如,可能会显示3个红绿灯组件,每个组件根据三个不同数据的设置更改颜色,让我们将它们称为light1,light2和light3。该组件有一个名为updateColor(int data)的函数,它将相应地更新颜色。

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

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

我已阅读有关绑定的内容,但我见过的所有示例似乎都没有解决这种情况。任何想法或指向一些类似例子的指针将不胜感激。

1 个答案:

答案 0 :(得分:2)

If the values are being updated in a background thread, you cannot bind properties of the UI components to them, as this would result in the UI properties being updated in the background thread. Properties of nodes that are part of the scene graph can only be updated on the FX Application Thread.

One idiom for managing this is to register a listener with the properties, and update the UI from a call to Platform.runLater(...) when it changes. Assuming, say, light1 is an instance of a Property<T> for some type T this would look like

light1.addListener((obs, oldValue, newValue) -> 
    Platform.runLater(() -> {
        // update UI with newValue...
    }));

The alternative here is to let the background thread update the properties on the FX Application Thread; i.e. the background thread invokes Platform.runLater(...) to update the properties. Then, since the properties are only being changes on the FX Application Thread, it is safe to bind UI properties to them:

// background thread code:

public void run() {

    // ...

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

}

and then you can do

someUIElement.someProperty().bind(light1);

(or replace light1 with some binding that is derived from light1).

For more general strategies for integrating background services into JavaFX, see the excellent article by Adam Bien.