Kotlin 将`FXTask`消息绑定到`Label`而不在FX中进行组件耦合
你好。我想知道是否有一种方便或简化的方法可以将Kotlin 将`FXTask`消息绑定到`Label`而不在FX中进行组件耦合,kotlin,tornadofx,Kotlin,Tornadofx,你好。我想知道是否有一种方便或简化的方法可以将fxstask的messageProperty和runningProperty绑定到Label的textProperty和Label属性,而不耦合fxstask和本身 例如,在下面的示例应用程序中,我通过将标签的引用耦合到任务来绑定messageProperty,这引入了一个额外的lateinit var statusLabel。类似地,我通过将任务的引用耦合到一个标签来绑定runningProperty,该标签引入了一个额外的val任务 class
fxstask
的messageProperty
和runningProperty
绑定到Label
的textProperty
和Label
属性,而不耦合fxstask
和本身
例如,在下面的示例应用程序中,我通过将标签的引用耦合到任务来绑定messageProperty
,这引入了一个额外的lateinit var statusLabel
。类似地,我通过将任务的引用耦合到一个标签来绑定runningProperty
,该标签引入了一个额外的val任务
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)
class DummyView:View(“虚拟视图”){
覆盖val root=vbox{
lateinit var状态标签:标签
val task=object:task(){
public override fun call():Void{
Platform.runLater{statusLabel.textProperty().bind(messageProperty())}//标签耦合
updateMessage(“正在初始化任务…”)
(1..3)forEach{
线程。睡眠(1000)
updateMessage(“正在执行任务:$it…”)
}
线程。睡眠(1000)
更新消息(“任务完成”)
线程。睡眠(1000)
返回空
}
}
按钮(“执行任务”){
行动{
线程(任务)。应用{//任务耦合
isDaemon=true
}.start()
}
}
statusLabel=标签(“状态”){
visibleWhen(task.runningProperty())//任务耦合
}
}
}
类DummyApp:App(DummyView::类)
有一个TaskStatus
对象可以传递到runAsync
中。此对象具有您正在运行的任务的所有有趣属性。无需子类化任务
或:)
您甚至可以通过注入自动可用的taskStatus来使用它。如果未将TaskStatus的特定实例传递给runAsync,则将获得默认实例。因此,这也是可行的:(区别在于TaskStatus被注入,TaskStatus的任何实例都不会传递给runAsync)
谢谢,这正是我想要的。我还有一个问题:何时首选创建TaskStatus
的实例,何时首选注入它?每种方法的优缺点是什么?如果没有对任务的引用,如何取消该任务?注入的TaskStatus
由在同一范围内运行的每个异步作业共享,因此这样做非常方便。如果需要更严格的控制,或者希望在ui中同时显示多个任务的进度,则需要实例化单独的TaskStatus
对象,并将它们传递到每个runAsync
调用中。要取消任务,可以插入任务和调用站点都可以访问的ViewModel。您还可以手动实例化一个对象并将其传入。如果在该对象内的属性中设置了某个值,则任务将知道如何取消。
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)
}
}
}
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)
}
}
}