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

JavaFX自定义DatePicker TableCell筛选表格时日期显示错位问题

JavaFX TableView筛选后DatePicker单元格内容错位问题

问题表现

为单元格选择日期时功能正常:
正常选择日期截图
触发FilteredList筛选谓词过滤后,已选日期错位显示到表格底部,恢复筛选规则后日期回到正确位置:
筛选后错位截图

问题原因

  • 核心原因是自定义DatePickerTableCell未重写updateItem()方法。JavaFX的TableCell采用复用机制,列表筛选、排序、滚动导致视图变化时,单元格会被重用来绑定不同行的数据,原有逻辑只在编辑提交、取消编辑时更新显示内容,没有在单元格复用时重置状态,导致旧内容残留错位。
  • 实体类SetterGetter未遵循JavaFX属性绑定规范,日期属性未正确初始化、缺少标准属性访问器,编辑提交的值没有持久化到实体的可观察属性中,列表刷新时单元格无法获取正确的绑定值。
  • 原有commitEdit()逻辑中手动调用setItem()属于错误操作,该方法由框架内部管理单元格状态,手动调用会打乱单元格的生命周期状态。

修复方案

  1. 为DatePickerTableCell重写updateItem()方法,统一处理空单元格、编辑状态、非编辑状态的显示逻辑,确保单元格复用时能根据当前绑定的数据正确更新内容。
  2. 修正SetterGetter实体类,按照JavaFX Bean规范实现日期属性的访问器,初始化属性避免空指针,确保编辑值能正确写入实体。
  3. 移除错误的手动setItem()调用,调整列的CellValueFactory绑定到正确的属性对象,修正初始化、新增行的传参逻辑。

修正后的DatePickerTableCell代码

import javafx.event.ActionEvent;
import javafx.scene.control.DatePicker;
import javafx.scene.control.TableCell;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class DatePickerTableCell extends TableCell<SetterGetter, LocalDate> {
    private final DatePicker datePicker = new DatePicker();
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    public DatePickerTableCell() {
        datePicker.setOnAction((ActionEvent event) -> commitEdit(datePicker.getValue()));
    }

    @Override
    protected void updateItem(LocalDate item, boolean empty) {
        super.updateItem(item, empty);
        if (empty || item == null) {
            setText(null);
            setGraphic(null);
            return;
        }
        if (!isEditing()) {
            setText(item.format(DATE_FORMATTER));
            setGraphic(null);
        } else {
            datePicker.setValue(item);
            setText(null);
            setGraphic(datePicker);
        }
    }

    @Override
    public void startEdit() {
        super.startEdit();
        datePicker.setValue(getItem());
        setText(null);
        setGraphic(datePicker);
        datePicker.requestFocus();
    }

    @Override
    public void cancelEdit() {
        super.cancelEdit();
        setText(getItem() == null ? null : getItem().format(DATE_FORMATTER));
        setGraphic(null);
    }

    @Override
    public void commitEdit(LocalDate newValue) {
        super.commitEdit(newValue);
        SetterGetter rowData = getTableView().getItems().get(getIndex());
        rowData.setDate(newValue);
        setText(newValue == null ? null : newValue.format(DATE_FORMATTER));
        setGraphic(null);
    }
}

修正后的SetterGetter实体类代码

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import java.time.LocalDate;

public class SetterGetter {
    private int id;
    private String name;
    private final ObjectProperty<LocalDate> date;
    private int status;

    public SetterGetter(int id, String name, LocalDate date, int status) {
        this.id = id;
        this.name = name;
        this.date = new SimpleObjectProperty<>(date);
        this.status = status;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public ObjectProperty<LocalDate> dateProperty() {
        return date;
    }

    public LocalDate getDate() {
        return date.get();
    }

    public void setDate(LocalDate date) {
        this.date.set(date);
    }
}

Controller类需要调整的代码片段

// 修正日期列的绑定,绑定到属性对象
colDueDate.setCellValueFactory(b -> b.getValue().dateProperty());

// 修正初始化数据的传参
mainTaskList.addAll(
        new SetterGetter(0, null, (LocalDate) null, 1),
        new SetterGetter(1, null, (LocalDate) null, 1)
);

// 修正新增行方法的传参
@FXML
void addCheck(ActionEvent event) {
    mainTaskList.add(new SetterGetter(0,
            null,
            (LocalDate) null,
            0)
    );
}

其余原有主启动类、FXML布局代码不需要修改,调整后筛选、编辑、新增操作都不会再出现内容错位问题。

内容的提问来源于stack exchange,提问作者احمد ربايعة

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 12:21:22