在TornadoFX中将FXTask消息绑定到Label而不进行组件耦合 [英] Binding `FXTask` message to `Label` without component coupling in TornadoFX
问题描述
美好的一天.我想知道是否有一种方便或精简的方式来将FXTask
的messageProperty
和runningProperty
绑定到Label
的textProperty
和visibleWhen
属性,而无需本身耦合FXTask
和Label
?
Good day. I was wondering if there is a convenient or streamlined way of binding FXTask
's messageProperty
and runningProperty
to Label
's textProperty
and visibleWhen
property accordingly without coupling FXTask
and Label
themselves?
例如,在下面的示例应用程序中,我通过将标签的引用耦合到任务来绑定messageProperty
,该任务引入了额外的lateinit var statusLabel
.同样,我通过将任务的引用耦合到引入了额外val task
的标签的方式来绑定runningProperty
.
For example in the sample app below, I'm binding messageProperty
by coupling label's reference to a task, which introduces an extra lateinit var statusLabel
. Similarly, I'm binding runningProperty
by coupling task's reference to a label which introduces an extra val task
.
class DummyView : View("Dummy View") {
override val root = vbox {
lateinit var statusLabel: Label
val task = object : Task<Void>() {
public override fun call(): Void? {
Platform.runLater { statusLabel.textProperty().bind(messageProperty()) } // label coupling
updateMessage("Initializing task...")
(1..3).forEach {
Thread.sleep(1000)
updateMessage("Doing task: $it...")
}
Thread.sleep(1000)
updateMessage("Task done")
Thread.sleep(1000)
return null
}
}
button("Do task") {
action {
Thread(task).apply {// task coupling
isDaemon = true
}.start()
}
}
statusLabel = label("Status") {
visibleWhen(task.runningProperty()) // task coupling
}
}
}
class DummyApp : App(DummyView::class)
推荐答案
有一个TaskStatus
对象,可以将其传递到runAsync
中.该对象具有您正在运行的任务的所有有趣的属性.也不需要子类Task
:)
There is a TaskStatus
object that can be passed into runAsync
. This object has all the interesting properties of the task you're running. No need to subclass Task
either :)
class DummyView : View("Dummy View") {
val taskStatus = TaskStatus()
override val root = vbox {
button("Do task") {
action {
runAsync(taskStatus) {
updateMessage("Initializing task...")
(1..3).forEach {
Thread.sleep(1000)
updateMessage("Doing task: $it...")
}
Thread.sleep(1000)
updateMessage("Task done")
Thread.sleep(1000)
}
}
}
label(taskStatus.message) {
visibleWhen(taskStatus.running)
}
}
}
您甚至可以简单地通过注入来使用自动可用的taskStatus.如果不将TaskStatus的特定实例传递给runAsync,则将获得默认实例.因此,这也适用:(区别是注入了TaskStatus,并且没有TaskStatus的实例传递给runAsync)
You could even use the automatically available taskStatus simply by injecting it. If you don't pass a specific instance of TaskStatus to runAsync, you'll get the default instance. Therefor this also works: (Difference is TaskStatus is injected, and no instance of TaskStatus is passed to runAsync)
class DummyView : View("Dummy View") {
val taskStatus: TaskStatus by inject()
override val root = vbox {
button("Do task") {
action {
runAsync {
updateMessage("Initializing task...")
(1..3).forEach {
Thread.sleep(1000)
updateMessage("Doing task: $it...")
}
Thread.sleep(1000)
updateMessage("Task done")
Thread.sleep(1000)
}
}
}
label(taskStatus.message) {
visibleWhen(taskStatus.running)
}
}
}
这篇关于在TornadoFX中将FXTask消息绑定到Label而不进行组件耦合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!