Есть ли способ обновить FX-Properties из другого потока без Platform.runLater () в kotlin? - PullRequest
0 голосов
/ 04 октября 2019

Я пытаюсь выучить kotlin и у меня проблема с темой TornadoFX.

В JavaFX я мог бы обновить наблюдаемые Свойства в другом потоке, и Обновления будут происходить в представлении без триггера, используя «Platform.runLater ()»

ОБНОВЛЕНИЕ :

Все, что я предположил о безопасности потоков в JFX, неверно!

Обновляйте только элементы пользовательского интерфейса или свойства, связанные с потоком пользовательского интерфейса, с помощью Platform.runLater (), Tasks или Animationtimer, никогда не извнебез Platform.runLater ().

Хотя вам следует осторожно использовать Platform.runLater (), поскольку у вас мало контроля над тем, что будет добавлено в поток пользовательского интерфейса, и это может вызвать некоторые раздражения.

Ниже этой точки приведены мои неправильные представления :

Вот что прекрасно работает в JavaFX работает, но также неверно


   @Fxml
   ProgressBar progress;

   @Fxml
   public void initialize(){
        DoubleProperty prop = new SimpleDoubleProperty(0);
        progress.progressProperty().bind(prop);
        ExecutorService ex = Executors.newSingleThreadExector();
        ex.execute(()->{
          while(true){
             Thread.sleep(2000);
             prop.set(prop.get()+0.1);

       }
   }


   }


По сути тот же код, но в Kotlin. не работает и создает исключение:

Не в потоке приложения FX;currentThread = Thread-3 TornadoFX


class test : View() {
    override val root: BorderPane by fxml("/views/primary.fxml")

    val counter = SimpleDoubleProperty()
    val progress: ProgressBar by fxid()

    init {
         thread{
                while(true){
                 Thread.sleep(2000)
                 counter.value += 0.1
                }
             }

        progress.bind(counter)


    }



}


Я ожидал, что они будут работать одинаково. Я мог бы исправить это с помощью «Platform.runLater (() -> ...)», но я не хочу ставить все в очередь в потоке пользовательского интерфейса, когда он уже наблюдает за свойствами. Я думал, что это было единственной целью возможности связать что-то с элементом пользовательского интерфейса.

Я неправильно использую свойства и привязки или это TornadoFX проблема ?

1 Ответ

0 голосов
/ 05 октября 2019

Я обнаружил проблему. Я сгенерировал свойство в элементе пользовательского интерфейса (View ()). Свойства в FX-UI связаны с потоком пользовательского интерфейса.

Мне просто нужно было сгенерировать, чтобы убедиться, что свойство, которое я хочу связать, находится вне ВИДА-потока

Вот пропер способ избежать "runLater () "

object TestThread{
    val property = SimpleDoubleProperty()
    val elapsedSeconds = SimpleLongProperty(0);
    init{
        println("start thread")
        val timer = object : AnimationTimer() {
            override fun handle(now: Long){
                if((now - elapsedSeconds.value)> 100000000){
                    property.value+=0.01
                    elapsedSeconds.value = now
                }

            }
        }
        timer.start()

    }
}

class HelloWorld : View() {
    exception  
   thread

    override val root: BorderPane by fxml("/views/primary.fxml")

    val counter = SimpleDoubleProperty()
    val pro = ProgressBar()


    init {


        root.right{
            add(pro)
        }
        // Now  bind the Property from THE ANIMATION to the UI-element wich
        // wich Observes the changes of the Property with no problem at all
        val t = TestThread
        pro.bind(t.property);
        incr.bind(counter)


    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...