TreeView 使用大图形节点时滚动跳转(TornadoFX/JavaFX)

TreeView scrolling jumps when using large graphic nodes (TornadoFX/JavaFX)

在下面的TornadoFX/Kotlin代码中

import javafx.scene.control.TreeItem
import javafx.scene.control.TreeView
import tornadofx.*

class MyObj {

    var type : Int = 0

    constructor(type : Int) {

        this.type = type
    }
}

class MainView: View("Minimal TV demo") {

    var treeRoot : TreeItem<MyObj> = TreeItem()
    var objectsTreeView : TreeView<MyObj>? = null

    override val root = vbox {

        objectsTreeView = treeview(treeRoot) {

            showRootProperty().value = false

            cellFormat {

                if(it.type == 0) {

                    text = "Test"
                    graphic = null
                }
                else {

                    text = null
                    graphic = vbox {

                        label("Label 1")
                        button("123")
                        textarea {

                                prefWidth = 100.0
                                prefHeight = 125.0
                        }
                    }
                }
            }
        }
    }

    init {

        with (root) {

            for(i in 1..10) {

                val x = TreeItem(MyObj(0))
                treeRoot.children.add(x)

                x.children.add(TreeItem(MyObj(1)))
            }
        }
    }
}

当打开一些树项目并滚动树视图时,树视图内容和滑块似乎表现得相当 "jumpy",即当我向下移动滑块时,鼠标移动但滑块和内容停留在原处,直到鼠标向下移动那么远,然后内容跳转。只是感觉或看起来不太好。

我相信我可以通过为每个 UI 元素行添加单独的 TreeItem 来解决这个问题,但是有没有办法在不这样做的情况下实现平滑滚动?我尝试使用固定的单元格高度,这似乎可行,但当然这看起来根本不正确,因为有些行比其他行短。

不要对复杂的树 UI 使用 cellFormat,因为元素将被非常快速地重新创建并且很可能导致闪烁。最好的办法是创建 TreeCellFragment 的子类并使用 cellFragment 调用对其进行配置。

现在您可以为每个 Tree 单元格仅创建一次 UI,并在它代表的数据发生变化时重新使用它。这更高效。