You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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));
    }
}
问题原因与修复方案

核心问题:类型不匹配导致数据无法传递

  1. cellValueFactory方法声明返回SimpleStringProperty,但TaskTreeTableViewCellValueFactory的call方法实际返回的是ReadOnlyStringWrapper,二者属于不同类体系(无继承关系),运行时会出现隐式类型转换错误,导致单元格无法获取正确数据,最终updateItem的参数s为null。
  2. TaskTreeTableViewCellValueFactory的call方法声明返回SimpleStringProperty,与接口定义的ObservableValue<String>不符,属于编译层面的错误。

修复步骤

  1. 修改cellValueFactory方法的返回类型为ObservableValue<String>,与接口返回类型保持一致:
private ObservableValue<String> cellValueFactory(CellDataFeatures<TaskBean, String> cdf, LocalDate date)
{
    return new TaskTreeTableViewCellValueFactory(date).call(cdf);
}
  1. 修正TaskTreeTableViewCellValueFactory中call方法的返回类型声明:
@Override public ObservableValue<String> call(TreeTableColumn.CellDataFeatures<TaskBean, String> cellDataFeatures)
{
    return readOnlyStringWrapperFor(cellDataFeatures.getValue().getValue());
}
  1. (可选)在自定义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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 09:07:34