如何在JavaFX TableView中使用GregorianCalendar并正确显示日期?
在JavaFX TableView中使用GregorianCalendar并格式化日期列的方案
当然可以在JavaFX TableView里用GregorianCalendar!不用再频繁在Date和它之间来回切换,核心就是给日期列自定义一个单元格工厂,让它按照你想要的格式显示,而不是默认的冗长toString()输出。我给你一步步拆解怎么做:
1. 准备包含GregorianCalendar的 data model
首先你的实体类要把GregorianCalendar包装在ObjectProperty里,这样TableView才能监听数据变化并自动更新:
import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import java.util.GregorianCalendar; public class ScheduleItem { private final StringProperty title; private final ObjectProperty<GregorianCalendar> scheduleDate; public ScheduleItem(String title, GregorianCalendar scheduleDate) { this.title = new SimpleStringProperty(title); this.scheduleDate = new SimpleObjectProperty<>(scheduleDate); } // Getter、Setter和Property方法 public String getTitle() { return title.get(); } public void setTitle(String title) { this.title.set(title); } public StringProperty titleProperty() { return title; } public GregorianCalendar getScheduleDate() { return scheduleDate.get(); } public void setScheduleDate(GregorianCalendar scheduleDate) { this.scheduleDate.set(scheduleDate); } public ObjectProperty<GregorianCalendar> scheduleDateProperty() { return scheduleDate; } }
2. 给日期列自定义单元格工厂
默认情况下,TableView会调用GregorianCalendar.toString(),所以才会显示那种java.util.GregorianCalendar[time=?areFieldsSet=false...]的内容。我们要重写单元格的updateItem方法,把GregorianCalendar转换成可格式化的日期对象,再用DateTimeFormatter输出规范格式:
import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; import javafx.util.Callback; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.GregorianCalendar; // 创建日期列 TableColumn<ScheduleItem, GregorianCalendar> dateColumn = new TableColumn<>("日程日期"); dateColumn.setCellValueFactory(cellData -> cellData.getValue().scheduleDateProperty()); // 设置自定义单元格工厂 dateColumn.setCellFactory(column -> new TableCell<ScheduleItem, GregorianCalendar>() { // 定义你想要的日期格式,比如"yyyy-MM-dd HH:mm:ss"或者"yyyy年MM月dd日" private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); @Override protected void updateItem(GregorianCalendar calendar, boolean empty) { super.updateItem(calendar, empty); // 空单元格或无数据时不显示内容 if (empty || calendar == null) { setText(null); } else { // 将GregorianCalendar转成ZonedDateTime,再用格式化器输出 ZonedDateTime zonedDateTime = calendar.toZonedDateTime(); setText(formatter.format(zonedDateTime)); } } });
额外小提示
- 如果只需要显示日期(不需要时间),可以把格式改成
"yyyy-MM-dd",完全根据你的需求调整即可。 - 要是需要支持用户编辑日期列,可以把单元格改成可编辑状态,嵌入
DatePicker组件,同样基于GregorianCalendar做转换就行,不用切换到Date类型。 - 虽然Java 8+更推荐用
java.time包的日期类(比如LocalDate、ZonedDateTime),但如果项目必须用GregorianCalendar,上面的方案完全能解决你的问题。
内容的提问来源于stack exchange,提问作者Kyu Vulpes
相关产品推荐
相关产品推荐

