Почему мой tornadoFX ObservableList не получает обновления? - PullRequest
0 голосов
/ 20 мая 2018

У меня есть простая программа tornadoFX, которая генерирует несколько кругов в случайных местах на экране.Однако ни один из кругов не нарисован.Я добавил некоторый отладочный код для печати линии, когда нарисована окружность, и она печатается только один раз.

Я ожидаю, что круги будут появляться с интервалами 100 мс, а также когда я нажимаю «Добавить актера»Кнопка.

private const val WINDOW_HEIGHT = 600
private const val WINDOW_WIDTH = 1024

fun main(args: Array<String>) {
    Application.launch(MainApp::class.java, *args)
}

class MainApp : App(WorldView::class, Stylesheet::class)

data class Actor(val x: Double, val y: Double)

class WorldView: View("Actor Simulator") {
    override val root = VBox()
    private val actors = ArrayList<Actor>(0)

    init {
        tornadofx.runAsync {
            (0..100).forEach {
                val x = ThreadLocalRandom.current().nextDouble(0.0, WINDOW_WIDTH.toDouble())
                val y = ThreadLocalRandom.current().nextDouble(0.0, WINDOW_HEIGHT.toDouble())
                actors.add(Actor(x, y))
                Thread.sleep(100)
            }
        }
    }

    init {
        with(root) {
            stackpane {
                group {
                    bindChildren(actors.observable()) {
                        circle {
                            centerX = it.x
                            centerY = it.y
                            radius = 10.0
                            also {
                                println("drew circle")
                            }
                        }
                    }
                }
                button("Add actor") {
                    action {
                        actors.add(Actor(0.0, 0.0))
                    }
                }
            }
        }
    }
}

Как ни странно, если я установлю точку останова во время кода рисования круга, круги начнут рисоваться и будет выведена строка отладки.

1 Ответ

0 голосов
/ 20 мая 2018

Некоторые наблюдения:

  1. Вызов someList.observable() создаст наблюдаемый список, подкрепленный базовым списком, но мутации в базовом списке не будут генерировать события.Вместо этого вы должны сразу инициализировать actors как наблюдаемый список.

  2. Доступ к наблюдаемому списку должен происходить в потоке пользовательского интерфейса, поэтому вам нужно заключить вызовы мутации в runLater.

  3. Для людей, пытающихся запустить ваш пример - вы не включили таблицу стилей, но ссылаетесь на нее в своем подклассе App, поэтому IDEA, скорее всего, импортирует TornadoFX Stylesheetучебный класс.Это не закончится хорошо:)

  4. Вызов also не имеет никакого эффекта, поэтому я удалил его.

  5. Я обновил ваш код долучшие практики здесь и там, например, в отношении того, как создать корневой узел:)

Обновленный пример с учетом этих точек выглядит следующим образом:

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))
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...