JavaFX TreeTableColumn自定义CellFactory后updateItem参数始终为null
问题描述
自定义TaskTreeTableColumn类,未添加CellFactory时,TreeTableView可正常填充数据;添加自定义CellFactory后,TreeTableCell的updateItem方法参数s始终为null,所有单元格显示空白。相关代码如下:
自定义TaskTreeTableColumn类
public class TaskTreeTableColumn extends TreeTableColumn<TaskBean, String> { public TaskTreeTableColumn(LocalDate date) { super("" + date.getDayOfMonth()); setCellValueFactory(cdf -> cellValueFactory(cdf, date)); setCellFactory (ttc -> cellFactory(ttc)); } private SimpleStringProperty cellValueFactory(CellDataFeatures<TaskBean, String> cdf, LocalDate date) { return new TaskTreeTableViewCellValueFactory(date).call(cdf); } private TreeTableCell<TaskBean, String> cellFactory(TreeTableColumn<TaskBean, String> ttc) { return new TreeTableCell<>() { @Override protected void updateItem(String s, boolean b) { setAlignment(Pos.CENTER); super.updateItem(s, b); } }; } }
TaskTreeTableViewCellValueFactory实现
public class TaskTreeTableViewCellValueFactory implements Callback<TreeTableColumn.CellDataFeatures<TaskBean, String>, ObservableValue<String>> { private final @NonNull LocalDate date; @Override public SimpleStringProperty call(TreeTableColumn.CellDataFeatures<TaskBean, String> cellDataFeatures) { return readOnlyStringWrapperFor(cellDataFeatures.getValue().getValue()); } private ReadOnlyStringWrapper readOnlyStringWrapperFor(TaskBean taskBean) { return new ReadOnlyStringWrapper(calculateSomeStringForTaskBasedOnDate(taskBean, date)); } }
问题原因与修复方案
核心问题:类型不匹配导致数据无法传递
cellValueFactory方法声明返回SimpleStringProperty,但TaskTreeTableViewCellValueFactory的call方法实际返回的是ReadOnlyStringWrapper,二者属于不同类体系(无继承关系),运行时会出现隐式类型转换错误,导致单元格无法获取正确数据,最终updateItem的参数s为null。TaskTreeTableViewCellValueFactory的call方法声明返回SimpleStringProperty,与接口定义的ObservableValue<String>不符,属于编译层面的错误。
修复步骤
- 修改
cellValueFactory方法的返回类型为ObservableValue<String>,与接口返回类型保持一致:
private ObservableValue<String> cellValueFactory(CellDataFeatures<TaskBean, String> cdf, LocalDate date) { return new TaskTreeTableViewCellValueFactory(date).call(cdf); }
- 修正
TaskTreeTableViewCellValueFactory中call方法的返回类型声明:
@Override public ObservableValue<String> call(TreeTableColumn.CellDataFeatures<TaskBean, String> cellDataFeatures) { return readOnlyStringWrapperFor(cellDataFeatures.getValue().getValue()); }
- (可选)在自定义
TreeTableCell的updateItem方法中显式设置文本,确保内容稳定显示:
private TreeTableCell<TaskBean, String> cellFactory(TreeTableColumn<TaskBean, String> ttc) { return new TreeTableCell<>() { @Override protected void updateItem(String s, boolean b) { super.updateItem(s, b); setAlignment(Pos.CENTER); setText(s == null ? "" : s); } }; }
内容的提问来源于stack exchange,提问作者r-uu
相关产品推荐
相关产品推荐

