Раньше мне никогда не приходилось использовать bindChildren
для TornadoFX, а использование asyn c не очень важно для того, что я считаю вашей основной проблемой. Итак, по общему признанию, этот вопрос сначала смутил меня, но я предполагаю, что вам просто интересно, почему список не появляется в вашем TreeView
? Я сделал тестовый пример с изменениями, чтобы он работал.
// Category
interface Category<T : Category<T>> {
val id: String
val name: String
val subcategories: List<T>?
}
//default category:
class DefaultCategory(override val name: String) : Category<DefaultCategory> {
override val id: String = "default"
override val subcategories: List<DefaultCategory>? = null
}
//Just a dummy category
class ChildCategory(override val name: String) : Category<ChildCategory> {
override val id = name
override val subcategories: List<ChildCategory>? = null
}
//ViewModel
class CategoryViewModel : ViewModel() {
//filled with dummy data
val sourceProperty = SimpleListProperty<Category<*>>(listOf(
ChildCategory("Categorya"),
ChildCategory("Categoryb"),
ChildCategory("Categoryc"),
ChildCategory("Categoryd")
).asObservable())
fun loadData() {
sourceProperty.asyncItems {
//items grabbed somehow
listOf(
ChildCategory("Category1"),
ChildCategory("Category2"),
ChildCategory("Category3"),
ChildCategory("Category4")
).asObservable()
}
}
}
class TestView : View() {
val model: CategoryViewModel by inject()
override val root = vbox(10) {
button("Refresh Items").action {
model.loadData()
}
add(createTreeView(model.sourceProperty))
}
// TreeViewFactoryMethod
private fun createTreeView(
listProperty: SimpleListProperty<Category<*>>
): TreeView<Category<*>> {
return treeview {
root = TreeItem(DefaultCategory("Categories"))
isShowRoot = false
root.isExpanded = true
root.children.forEach { it.isExpanded = true }
cellFormat { text = it.name }
populate { parent ->
when (parent) {
root -> listProperty
else -> parent.value.subcategories
}
}
}
}
}
Есть 2 важных отличия, которые важны.
1. Более важное различие заключается в том, что внутри блока заполнения вместо root.listProperty.value
используется root -> listProperty
. Это сделает ваш список появиться. Причина в том, что SimpleListProperty
не является списком, он содержит список. Так что да, передача в простой список вполне допустима (например, как вы передали значение свойства списка). Но теперь это означает, что древовидное представление не слушает вашу собственность, а только список, который вы передали. Имея это в виду, я бы подумал над реализацией списков подкатегорий категорий.
2. Во-вторых, обратите внимание на использование asyncItems
в ViewModel
. Это будет выполнять любую задачу асинхронно, а затем установить список элементов в случае успеха. Вы можете даже добавить fail
или cancel
блоки к нему. Я бы рекомендовал использовать это, поскольку длинные / интенсивные операции не должны выполняться в потоке пользовательского интерфейса.