JavaFX Cell 和 setCellFactory 混淆
JavaFX Cell and setCellFactory confusion
我正在学习细胞和细胞工厂API。我已经阅读了很多示例,但我无法理解 setCellFactory 或 setCellValuesFactory 的实际工作原理。
以下是 Scala 中的示例(向 Java 用户致歉):
#1:
val cb = new javafx.util.Callback[ListView[Number], ListCell[Number]] {
override def call(list: ListView[Number]): ListCell[Number] = {
new MoneyFormatCell
}
}
#2:
class TranslationCell extends ListCell[String] {
override protected def updateItem(item: String, empty: Boolean) {
super.updateItem(item, empty)
textProperty().unbind()
if (empty || item == null) setText("") ?else textProperty().bind(createStringBinding(item))
}
}
请忽略 Callback 和 TranslationCell 中的不同类型和登录 class,它们与本例无关。
现在,如果我这样做,两个选项都有效:
x.setCellFactory(cb)
y.setCellFactory(lv => new TranslationCell)
我不明白 y
案例如何或为什么工作,因为 setCellFactory
需要一个 Callback[A]
和一个扩展 ListCell[B]
的 TranslationCell
实例].
我也不明白 updateItem
方法与函数有什么关系,以及如何将 TranslationCell
的实例毫无问题地传递给 setCellFactory
。
updateItem
和setCellFactory
有什么关系?
setCellFactory
方法采用 Callback<ListView<T>,ListCell<T>>
,即函数将 ListView<T>
映射到 ListCell<T>
。在您发布的代码中,您没有将 ListCell
传递给 setCellFactory
方法。
ListView
通过创建显示可见内容所需的尽可能多的单元格在内部工作。请注意,由于 ListView
是可滚动的,因此这可能比 ListView
中包含的项目数少很多。 ListCell
是通过根据需要多次调用传递给 setCellFactory()
方法的 Callback
来创建的,以创建所需数量的单元格。通常,如果 ListView
足够大以显示,例如 10 个细胞,它会调用细胞工厂的 Callback
至少 10 次(它可能会创建一个或两个“备用”细胞)。
为了实际显示单元格的内容,ListView
会调用每个单元格的updateItem()
方法,传入要显示的项目(或null
),并且表示此单元格是否为“空”的布尔值。 updateItem()
方法的实现应该设置要显示的基于item
的单元格的文本and/or图形。
在细胞生命周期的不同阶段,可能会要求它显示不同的项目。例如,当用户在 ListView
周围滚动时,不是为新显示的项目创建新单元格并丢弃旧单元格(这在某些时候会给垃圾收集器带来相当大的压力),ListView
将简单地“重用”现有单元格,要求它们显示不同的项目。这个的实际实现(故意)没有定义;您所知道的是,只要单元格需要更新其显示,就会调用 updateItem()
方法。
请注意,这意味着您的 updateItem()
方法需要处理所有可能性;它可能从空到非空,从非空到空,或者从显示一个项目到显示另一个项目。因此 updateItem()
方法必须在任何代码路径中设置文本 and/or 图形。如果您做其他事情,例如更改样式,您应该在 updateItem()
方法中的任何可能的代码路径中再次这样做。
我正在学习细胞和细胞工厂API。我已经阅读了很多示例,但我无法理解 setCellFactory 或 setCellValuesFactory 的实际工作原理。
以下是 Scala 中的示例(向 Java 用户致歉):
#1:
val cb = new javafx.util.Callback[ListView[Number], ListCell[Number]] {
override def call(list: ListView[Number]): ListCell[Number] = {
new MoneyFormatCell
}
}
#2:
class TranslationCell extends ListCell[String] {
override protected def updateItem(item: String, empty: Boolean) {
super.updateItem(item, empty)
textProperty().unbind()
if (empty || item == null) setText("") ?else textProperty().bind(createStringBinding(item))
}
}
请忽略 Callback 和 TranslationCell 中的不同类型和登录 class,它们与本例无关。
现在,如果我这样做,两个选项都有效:
x.setCellFactory(cb)
y.setCellFactory(lv => new TranslationCell)
我不明白 y
案例如何或为什么工作,因为 setCellFactory
需要一个 Callback[A]
和一个扩展 ListCell[B]
的 TranslationCell
实例].
我也不明白 updateItem
方法与函数有什么关系,以及如何将 TranslationCell
的实例毫无问题地传递给 setCellFactory
。
updateItem
和setCellFactory
有什么关系?
setCellFactory
方法采用 Callback<ListView<T>,ListCell<T>>
,即函数将 ListView<T>
映射到 ListCell<T>
。在您发布的代码中,您没有将 ListCell
传递给 setCellFactory
方法。
ListView
通过创建显示可见内容所需的尽可能多的单元格在内部工作。请注意,由于 ListView
是可滚动的,因此这可能比 ListView
中包含的项目数少很多。 ListCell
是通过根据需要多次调用传递给 setCellFactory()
方法的 Callback
来创建的,以创建所需数量的单元格。通常,如果 ListView
足够大以显示,例如 10 个细胞,它会调用细胞工厂的 Callback
至少 10 次(它可能会创建一个或两个“备用”细胞)。
为了实际显示单元格的内容,ListView
会调用每个单元格的updateItem()
方法,传入要显示的项目(或null
),并且表示此单元格是否为“空”的布尔值。 updateItem()
方法的实现应该设置要显示的基于item
的单元格的文本and/or图形。
在细胞生命周期的不同阶段,可能会要求它显示不同的项目。例如,当用户在 ListView
周围滚动时,不是为新显示的项目创建新单元格并丢弃旧单元格(这在某些时候会给垃圾收集器带来相当大的压力),ListView
将简单地“重用”现有单元格,要求它们显示不同的项目。这个的实际实现(故意)没有定义;您所知道的是,只要单元格需要更新其显示,就会调用 updateItem()
方法。
请注意,这意味着您的 updateItem()
方法需要处理所有可能性;它可能从空到非空,从非空到空,或者从显示一个项目到显示另一个项目。因此 updateItem()
方法必须在任何代码路径中设置文本 and/or 图形。如果您做其他事情,例如更改样式,您应该在 updateItem()
方法中的任何可能的代码路径中再次这样做。