TornadoFX - как исправить ListView с пользовательской фабрикой ячеек, которая не обновляется должным образом при удалении элементов?
У меня есть ListView
отображение пользовательских объектов из моей доменной модели, и если я использую собственную фабрику ячеек для отображения свойств объектов в каждой строке списка, я получаю странное поведение при удалении элементов. Если элемент не последний в списке, удаленный элемент остается видимым, а последний элемент исчезает. Тем не менее, элемент был удален из списка поддержки, как и ожидалось, и попытка удалить фантомный объект больше не имеет никакого эффекта.
Кажется, что дисплей не обновляется должным образом, потому что после некоторого произвольного изменения размера окна список в конечном итоге обновляется до ожидаемых значений. Я пробовал звонить refresh()
на ListView
вручную, но это не имеет заметного эффекта.
Удаление моей настраиваемой фабрики ячеек устраняет проблему, и я видел другие публикации, в которых была похожая проблема с использованием стандартного JavaFX ( ListView, использующий настраиваемую фабрику ячеек, не обновляется после удаленных элементов), где проблема была исправлена путем изменения реализации updateItem(Object item, boolean empty)
, но я не могу понять, как это сделать в TornadoFX.
Вот пример, который демонстрирует проблему обновления (но не элемент фантома, который происходит, только если кнопка удаления является частью пользовательской ячейки):
package example
import javafx.scene.control.ListView
import tornadofx.*
data class DomainClass(val name: String, val flag1: Boolean, val flag2: Boolean, val info: String)
class UpdateIssue : App(UpdateIssueView::class)
class UpdateIssueView : View() {
val listSource = mutableListOf(
DomainClass("object1", true, false, "more info"),
DomainClass("object2", false, true, "even more info"),
DomainClass("object3", false, false, "all the info")
).observable()
var lst: ListView<DomainClass> by singleAssign()
override val root = vbox {
lst = listview(listSource) {
cellFormat {
graphic = cache {
hbox {
textfield(it.name)
combobox<Boolean> {
selectionModel.select(it.flag1)
}
combobox<Boolean> {
selectionModel.select(it.flag2)
}
textfield(it.info)
}
}
}
}
button("delete") {
action {
listSource.remove(lst.selectedItem)
}
}
}
}
Любая помощь с благодарностью!
2 ответа
Предложение @Edvin Syse об удалении блока кеша исправило это для меня (хотя обратите внимание, что он также сказал, что более производительное исправление будет заключаться в реализации ListCellFragment
что я не сделал здесь):
....
lst = listview(listSource) {
cellFormat {
graphic = hbox {
textfield(it.name)
combobox<Boolean> {
selectionModel.select(it.flag1)
}
combobox<Boolean> {
selectionModel.select(it.flag2)
}
textfield(it.info)
}
}
}
Я заметил, что ComboBox не показывает никаких других выбираемых значений, кроме it.flag1 и flag2. Вы захотите установить для свойства values значение true/false или true/false/null. Затем вы можете установить значение элемента напрямую.
lst = listview(listSource) {
cellFormat {
graphic = hbox {
textfield(it.name)
combobox(values=listOf(true, false)) {
value = it.flag1
}
combobox(values=listOf(true, false)) {
value = it.flag2
}
textfield(it.info)
}
}
}