Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/github/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 为什么我的tornadoFX观察列表没有收到更新?_Kotlin_Tornadofx - Fatal编程技术网

Kotlin 为什么我的tornadoFX观察列表没有收到更新?

Kotlin 为什么我的tornadoFX观察列表没有收到更新?,kotlin,tornadofx,Kotlin,Tornadofx,我有一个简单的tornadoFX程序,可以在屏幕上的任意位置生成一些圆圈。然而,没有一个圆被画出来。我添加了一些调试代码,以便在绘制圆时打印一条线,并且它只打印一次 我希望圆圈以100毫秒的间隔出现,当我点击“添加演员”按钮时也是如此 private const val WINDOW\u HEIGHT=600 私有常量值窗口_宽度=1024 趣味主线(args:Array){ Application.launch(MainApp::class.java,*args) } 类MainApp:App

我有一个简单的tornadoFX程序,可以在屏幕上的任意位置生成一些圆圈。然而,没有一个圆被画出来。我添加了一些调试代码,以便在绘制圆时打印一条线,并且它只打印一次

我希望圆圈以100毫秒的间隔出现,当我点击“添加演员”按钮时也是如此

private const val WINDOW\u HEIGHT=600
私有常量值窗口_宽度=1024
趣味主线(args:Array){
Application.launch(MainApp::class.java,*args)
}
类MainApp:App(世界视图::类,样式表::类)
数据类参与者(val x:Double,val y:Double)
类WorldView:View(“参与者模拟器”){
重写val root=VBox()
private val actors=ArrayList(0)
初始化{
TornadFX.runAsync{
(0..100)forEach{
val x=ThreadLocalRandom.current().nextDouble(0.0,窗口宽度.toDouble())
val y=ThreadLocalRandom.current().nextDouble(0.0,窗口高度.toDouble())
actors.add(Actor(x,y))
线程。睡眠(100)
}
}
}
初始化{
带(根){
堆叠窗格{
团体{
bindChildren(actors.observable()){
圈{
centerX=it.x
centerY=it.y
半径=10.0
也{
println(“画圆”)
}
}
}
}
按钮(“添加参与者”){
行动{
actors.add(Actor(0.0,0.0))
}
}
}
}
}
}
奇怪的是,如果我在圆圈绘制代码期间放置断点,圆圈将绘制,调试行将打印。

一些观察结果:

  • 调用
    someList.observable()
    将创建一个由基础列表支持的可观察列表,但基础列表上的突变不会发出事件。您应该立即将
    actors
    初始化为可观察列表

  • 对可观察列表的访问必须发生在UI线程上,因此您需要在
    runLater
    中包装变异调用

  • 对于试图运行您的示例的人-您没有包含样式表,但在
    应用程序
    子类中引用了一个样式表,因此该想法很可能会导入TornadFX
    样式表
    类。这不会有好的结局:)

  • 调用也
    无效,因此我将其删除

  • 我在这里和那里更新了您的代码以获得最佳实践,例如关于如何创建根节点:)

  • 考虑到这些要点的更新示例如下所示:

    private const val WINDOW_HEIGHT = 600.0
    private const val WINDOW_WIDTH = 1024.0
    
    class MainApp : App(WorldView::class)
    
    data class Actor(val x: Double, val y: Double)
    
    class WorldView : View("Actor Simulator") {
    
        private val actors = FXCollections.observableArrayList<Actor>()
    
        override fun onDock() {
            runAsync {
                (0..100).forEach {
                    val x = ThreadLocalRandom.current().nextDouble(0.0, WINDOW_WIDTH.toDouble())
                    val y = ThreadLocalRandom.current().nextDouble(0.0, WINDOW_HEIGHT.toDouble())
                    runLater {
                        actors.add(Actor(x, y))
                    }
                    Thread.sleep(100)
                }
            }
        }
    
        override val root = stackpane {
            setPrefSize(WINDOW_WIDTH, WINDOW_HEIGHT)
            group {
                bindChildren(actors) {
                    circle {
                        centerX = it.x
                        centerY = it.y
                        radius = 10.0
                        println("drew circle")
                    }
                }
            }
            button("Add actor") {
                action {
                    actors.add(Actor(0.0, 0.0))
                }
            }
        }
    }
    
    private const val WINDOW\u HEIGHT=600.0
    私有常量值窗口的宽度=1024.0
    类MainApp:App(世界视图::类)
    数据类参与者(val x:Double,val y:Double)
    类WorldView:View(“参与者模拟器”){
    private val actors=FXCollections.observearraylist()
    覆盖fun onDock(){
    运行异步{
    (0..100)forEach{
    val x=ThreadLocalRandom.current().nextDouble(0.0,窗口宽度.toDouble())
    val y=ThreadLocalRandom.current().nextDouble(0.0,窗口高度.toDouble())
    朗莱特{
    actors.add(Actor(x,y))
    }
    线程。睡眠(100)
    }
    }
    }
    覆盖val root=stackpane{
    setPrefSize(窗宽、窗高)
    团体{
    儿童(演员){
    圈{
    centerX=it.x
    centerY=it.y
    半径=10.0
    println(“画圆”)
    }
    }
    }
    按钮(“添加参与者”){
    行动{
    actors.add(Actor(0.0,0.0))
    }
    }
    }
    }
    
    这个答案太棒了!但这让我想知道。。。对
    bindChildren
    的搜索结果很少,但它感觉像是一个完全核心的功能。当默认的表或列表视图不够用,并且我想对每个项目进行一些奇特的渲染时,除了使用
    bindChildren
    之外,别无选择。还是有别的办法?
    private const val WINDOW_HEIGHT = 600.0
    private const val WINDOW_WIDTH = 1024.0
    
    class MainApp : App(WorldView::class)
    
    data class Actor(val x: Double, val y: Double)
    
    class WorldView : View("Actor Simulator") {
    
        private val actors = FXCollections.observableArrayList<Actor>()
    
        override fun onDock() {
            runAsync {
                (0..100).forEach {
                    val x = ThreadLocalRandom.current().nextDouble(0.0, WINDOW_WIDTH.toDouble())
                    val y = ThreadLocalRandom.current().nextDouble(0.0, WINDOW_HEIGHT.toDouble())
                    runLater {
                        actors.add(Actor(x, y))
                    }
                    Thread.sleep(100)
                }
            }
        }
    
        override val root = stackpane {
            setPrefSize(WINDOW_WIDTH, WINDOW_HEIGHT)
            group {
                bindChildren(actors) {
                    circle {
                        centerX = it.x
                        centerY = it.y
                        radius = 10.0
                        println("drew circle")
                    }
                }
            }
            button("Add actor") {
                action {
                    actors.add(Actor(0.0, 0.0))
                }
            }
        }
    }