2016-10-04 2 views
0

Я очень новичок в JavaFX.
Я работаю над приложением, где у меня есть несколько компонентов графического интерфейса, которые меняют внешний вид на основе нескольких значений данных. Например, может отображаться 3 компонента светофора, каждый из которых меняет цвет на основе настроек трех разных частей данных, назовем их light1, light2 и light3. Компонент имеет функцию updateColor (int data), которая соответствующим образом обновит цвет.Использование JavaFX, как вы привязываете компоненты GUI к данным?

Существует отдельный поток, который периодически получает значения данных и обновляет значения в light1, light2 и light3.

Теперь я хочу, чтобы отображаемые компоненты автоматически меняли цвета, как только отдельный поток обновляет эти значения.

Я прочитал о привязке, но ни один из примеров, которые я видел, по-видимому, не затрагивает эту ситуацию. Любые идеи или указатели на некоторые подобные примеры были бы оценены.

+0

Возможный дубликат [Постоянно обновлять пользовательский интерфейс в рабочем потоке Java FX] (http://stackoverflow.com/questions/20497845/constantly-update-ui-in-java-fx-worker-thread) – fabian

ответ

2

Если значения обновляются в фоновом потоке, вы не можете связывать им свойства компонентов пользовательского интерфейса, так как это приведет к обновлению свойств пользовательского интерфейса в фоновом потоке. Свойства узлов, которые являются частью графика сцены, могут быть обновлены только в потоке приложения FX.

. Идиомой для управления этим является регистрация слушателя со свойствами и обновление пользовательского интерфейса от вызова до Platform.runLater(...) при его изменении. Предполагая, что, скажем, light1 является экземпляр Property<T> для некоторого типа T это будет выглядеть

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

Альтернатива здесь, чтобы фоновый поток обновляет свойства на FX Application Thread; то есть фоновый поток вызывает Platform.runLater(...) для обновления свойств. Тогда, так как свойства только быть изменения на FX Application Thread, безопасно связывать свойства пользовательского интерфейса для них:

// background thread code: 

public void run() { 

    // ... 

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

} 

, а затем вы можете сделать

someUIElement.someProperty().bind(light1); 

(или заменить light1 с некоторыми связывание, которое получено из light1).

Для получения более общих стратегий интеграции фоновых сервисов в JavaFX см. excellent article Адамом Биеном.

+0

Спасибо, Взглянем на это. –

+0

Ну, одна из проблем заключается в том, что фоновый поток не знает о графическом интерфейсе. Работа - это просто получить значения из внешнего источника и сохранить их локально. –

+0

Я не уверен, что понимаю. Вы сказали, что отдельный поток «периодически получает значения данных и обновляет значения в light1, light2 и light3». Итак, если вы сделаете эти свойства доступными извне, вы можете просто использовать первое решение ('light1.addListener ((...) -> Platform.runLater (...));'), no? Или вы можете использовать методы обратного вызова в статье Адама. –

Смежные вопросы