我ListView在JavaFX应用程序中使用a .列表中的项目需要的不仅仅是一个字符串来显示它们,所以我做了一个自定义实现ListCell<T>,其中T是我正在显示的对象的类.在这个自定义类中,我BorderPane在构造函数和覆盖中创建了一个updateItem(T item, boolean empty).我的想法是,当updateItem调用时,我将单元格的图形设置为BorderPane,同时更改Label其内部的s的一些属性.不过,我注意到updateItem不叫一次(例如,当一个细胞是通过滚动循环使用或添加新的项目),但它被称为所有的时间,例如,当从一个小区焦点切换到另一个(甚至无需滚动),或调整场景大小时,或按下边框内的按钮时,......
我需要一个ListView自定义ListCell的.我想在重用单元格时接收一个回调,传递新项目作为参数呈现.然后我想使用该项作为模型来构造一个视图 - 控制器对,我将其视图并将其用作graphic单元格.此视图中的按钮和其他控件应该可以工作.这在JavaFX中是否可行?
链接问题:
updateItem)基本思想是很少构建单元格,但updateItem(...)很可能经常调用该方法.没有实际保证该项目在呼叫之间确实发生了变化updateItem(...).默认实现updateItem(...)负责处理选择,焦点等,因此如果任何属性发生更改(即使项目未更改),可能需要调用此方法.
因此,您应该努力减少updateItem(...)方法的开销.目前尚不清楚多次频繁调用是否会阻止您执行所需操作(例如,当您将新项目作为参数传递给模型时,请检查它是否与您在进行任何更新之前已经存在的实际不同) .
我认为这updateItem(...)确实有些错误:它不仅在item更新时被调用,而且在任何时候都需要更新单元格.已经存在一种仅在item更改时执行代码的机制:只需向单元格注册一个侦听器itemProperty().您可以使用此技术(我通常更喜欢)来创建不同的样式ListCell:
ListView<...> listView = ... ;
listView.setCellFactory(lv -> {
BorderPane cellRoot = new BorderPane();
// create nodes, register listeners on them, populate cellRoot, etc...
ListCell<...> cell = new ListCell<>();
cell.itemProperty().addListener((obs, oldItem, newItem) -> {
if (newItem != null) {
// update cellRoot (or its child nodes' properties) accordingly
}
});
cell.emptyProperty().addListener((obs, wasEmpty, isEmpty) -> {
if (isEmpty) {
cell.setGraphic(null);
} else {
cell.setGraphic(cellRoot);
}
});
cell.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
return cell ;
});
Run Code Online (Sandbox Code Playgroud)
在您的方案中,此方法可能会更好.