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)
        }
    }
}
Другие вопросы по тегам