El text de la label no se actualiza aunque el hilo de la interfaz de usuario parece responder

Estoy construyendo una aplicación con TornadoFX 1.7.11 usando Kotlin 1.1.51 en JDK 8u121.

Estoy intentando ejecutar una tarea de larga duración en un hilo separado y mostrar el progreso en la UI usando una barra de progreso y una label. Extrañamente, la label no se está actualizando. Pensé que tal vez de alguna manera ejecuté la tarea en el hilo de la interfaz de usuario y está atascado, pero la barra de progreso funciona y la interfaz de usuario es receptiva (controles de trabajo, etc.).

Captura de pantalla con barra de progreso medio llena y mensajes de consola que muestran que el mensaje se ha actualizado. Una flecha roja apunta a un lugar donde debe estar la etiqueta, pero no hay texto visible allí.

También intenté editar manualmente la label con ScenicView y funcionó. No tengo ideas, ¿pueden ayudarme?

Aquí hay fragments de código algo simplificados:

MainView.kt

class MainView : View("") { private val controller: MainController by inject() override val root = borderpane { bottom(TasksView::class) } init { controller.reloadTranslations().completed.onChange { // do some lightweight UI stuff } } } 

MainController.kt

 class MainController : Controller() { private val tasksController: TasksController by inject() fun reloadTranslations(): TaskStatus { val task = TaskStatus() tasksController.tasks.add(task) runAsync(task) { updateMessage(messages["loadingTranslations"]) BibxCache.rebuild().subscribe { updateMessage(messages["loadingTranslations"] + " " + it.loaded) // for debugging updateProgress(it.loaded.toLong(), it.total.toLong()) } } return task } fun getTranslations() = BibxCache.values.toSortedSet() } 

TasksView.kt

 class TasksView : View() { override val root = vbox() val controller: TasksController by inject() init { controller.tasks.onChange { root.clear() controller.tasks.map { TaskRow(it) }.forEach { root.add(it) } } } } class TaskRow(task: TaskStatus) : HBox() { init { val progressBar = ProgressBar(task.progress.get()) progressBar.bind(task.progress) val label = Label(task.message.get()) label.bind(task.message) task.message.onChange { println(it) } // for debugging children.addAll( progressBar, Label(task.message.get()) ) } } 

TasksController.kt

 class TasksController : Controller() { val tasks: ObservableList<TaskStatus> = FXCollections.observableArrayList() init { tasks.onChange { change -> change.next() change.addedSubList.forEach { added -> added.completed.onChange { tasks.remove(added) } } } } } 

Su código no es ejecutable, pero creé una muestra mínima basada en estos conceptos, utilizando un enfoque más idiomático.

 class MainView : View("Tasks") { private val mainController: MainController by inject() override val root = borderpane { setPrefSize(600.0, 400.0) top { button("Start task").action { mainController.reloadTranslations() } } bottom(TasksView::class) } } class MainController : Controller() { private val tasksController: TasksController by inject() fun reloadTranslations(): TaskStatus { val task = TaskStatus() tasksController.tasks.add(task) runAsync(task) { updateMessage(messages["loadingTranslations"] + " $this...") Thread.sleep(Random().nextInt(2000).toLong()) updateMessage(messages["loadingTranslations"] + " $this - half way") updateProgress(50.0, 100.0) Thread.sleep(Random().nextInt(2000).toLong()) } return task } } class TasksView : View() { val controller: TasksController by inject() override val root = vbox { bindChildren(controller.tasks) { task -> hbox { progressbar(task.progress) label(task.message) } } } } class TasksController : Controller() { val tasks: ObservableList<TaskStatus> = FXCollections.observableArrayList() init { tasks.onChange { change -> change.next() change.addedSubList.forEach { added -> added.completed.onChangeOnce { tasks.remove(added) } } } } } 

Esto también se puede hacer con less fanfarria, pero no conozco la complejidad o los requisitos de tu aplicación, así que la cambié lo less posible 🙂

  • CellCache se representa inesperadamente en TableView con tornadoFX
  • TornadoFX envuelve las classs de dominio en ItemViewModel
  • Columnas de tabla dinámica
  • TornadoFX cómo enlazar Node style (o styleClass) a una propiedad?
  • Tornadofx - controlando el object de la fila de la vista de tabla mientras construye
  • java.lang.NoSuchMethodException cuando intenta ejecutar la aplicación TornadoFX
  • tornadofx EventBus expande la fila de la tabla usando el object tableview
  • Cómo ejecutar tornado fx hello world con java 7
  • ¿Cómo agregar leyenda secundaria al gráfico JavaFX?
  • tornadoFX togglebutton no tiene propiedad de text
  • Tornadofx - Cómo pasar el parámetro a Fragment en cada instancia