Mac*_*ich 11 java listview javafx custom-cell
我试图根据自ListView定义Cell列表定制自定义objects.
自定义对象是调用的类名Message,其中包含消息内容,收件人,时间戳和状态(读取,发送等)的几个字段.
看了这个问题:使用FXML在JavaFX中自定义ListView我已经成功:
但是,我无法链接两者:我似乎无法找到一种方法,以便ListView的当前项被发送到Cell Controller.
这是我的单元工厂代码和ListView项目填充:
final ObservableList observableList = FXCollections.observableArrayList();
observableList.setAll(myMessages); //assume myMessage is a ArrayList<Message>
conversation.setItems(observableList); //the listview
conversation.setCellFactory(new Callback<ListView<Message>, ListCell<Message>>() {
@Override
public ConversationCell<Message> call(ListView<Message> listView) {
return new ConversationCell();
}
});
Run Code Online (Sandbox Code Playgroud)
而现在,ConversationCell类:
public final class ConversationCell<Message> extends ListCell<Message> {
@Override
protected void updateItem(Message item, boolean empty) {
super.updateItem(item, empty);
ConversationCellController ccc = new ConversationCellController(null);
setGraphic(ccc.getView());
}
}
Run Code Online (Sandbox Code Playgroud)
我无法显示ConversationCellController,但我可以说,这是(在其构造函数中)我加载设计单元格的FXML文件,然后我可以用给定的Message项填充值.
该getView()方法返回包含现在填充和设计的单元格的根窗格.
正如我之前所说,设计工作,但我似乎无法将ListView项目与CellFactory链接,因为在方法中
protected void updateItem(消息项,布尔值为空)
empty设置为true,item确实为null.
我能做些什么来完成这项工作?
Jam*_*s_D 12
所有重写的自定义单元实现都updateItem(...)需要处理该方法中单元格为空的情况.所以你可以对此做一个天真的修复
public final class ConversationCell<Message> extends ListCell<Message> {
@Override
protected void updateItem(Message item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
} else {
// did you mean to pass null here, or item??
ConversationCellController ccc = new ConversationCellController(null);
setGraphic(ccc.getView());
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,从性能的角度来看,这不是一个好的解决方案.每次updateItem(...)使用非空单元格调用时都会加载FXML ,这是一个相当昂贵的操作(可能涉及文件i/o,从jar文件中解压缩FXML文件,解析文件,反射大量,创建新的UI元素等).每次用户滚动列表视图几个像素时,您都不希望FX应用程序线程执行所有工作.相反,您的单元格应该缓存节点并应该在updateItem方法中更新它:
public final class ConversationCell<Message> extends ListCell<Message> {
private final ConversationCellController ccc = new ConversationCellController(null);
private final Node view = ccc.getView();
@Override
protected void updateItem(Message item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
} else {
ccc.setItem(item);
setGraphic(view);
}
}
}
Run Code Online (Sandbox Code Playgroud)
您应该定义setItem(...)的方法ConversationCellController,更新视图(标签集文字,等等等等)相应.
| 归档时间: |
|
| 查看次数: |
14578 次 |
| 最近记录: |