如何在JavaFX TableView中设置动态计算列(无需写入SQLite)
实现JavaFX TableView到期剩余时间列的动态展示与自动更新
步骤1:抽离时间计算逻辑为工具方法
把你的时间计算逻辑单独封装,优化日期处理(直接用LocalDate对象而非字符串解析,避免格式异常):
private String calculateTimeLeft(Medicaments item) { // 获取当前行药品的过期日期 LocalDate expiryDate = dateExpiry.getCellObservableValue(item).getValue(); if (expiryDate == null) { return "无过期日期"; } LocalDate today = LocalDate.now(); long daysBetween = ChronoUnit.DAYS.between(today, expiryDate); // 处理已过期的情况 if (daysBetween < 0) { return "已过期 " + Math.abs(daysBetween) + " 天"; } int years = (int) daysBetween / 365; int remainingDaysAfterYears = (int) daysBetween % 365; int months = remainingDaysAfterYears / 30; int days = remainingDaysAfterYears % 30; return years + " 年 " + months + " 个月 " + days + " 天 (" + daysBetween + " 天)"; }
步骤2:创建剩余时间列并绑定计算逻辑
通过**单元格工厂(Cell Factory)**动态计算每行的剩余时间,无需提前生成列表再批量赋值:
// 创建剩余时间列 TableColumn<Medicaments, String> timeLeftColumn = new TableColumn<>("到期剩余时间"); // 设置单元格工厂,实时计算单元格内容 timeLeftColumn.setCellFactory(column -> new TableCell<Medicaments, String>() { @Override protected void updateItem(String item, boolean empty) { super.updateItem(item, empty); if (empty || getTableRow() == null || getTableRow().getItem() == null) { setText(null); return; } // 获取当前行的药品数据,计算剩余时间并显示 Medicaments medicament = getTableRow().getItem(); setText(calculateTimeLeft(medicament)); } }); // 将列添加到TableView ExpiryTableView.getColumns().add(timeLeftColumn);
步骤3:实现每日自动更新
用JavaFX的Timeline定时触发表格刷新,确保每天自动更新剩余时间:
// 创建每日更新的时间线 Timeline dailyUpdateTimeline = new Timeline( new KeyFrame(Duration.ZERO, event -> ExpiryTableView.refresh()), new KeyFrame(Duration.hours(24)) ); // 设置无限循环 dailyUpdateTimeline.setCycleCount(Animation.INDEFINITE); // 启动定时任务 dailyUpdateTimeline.play();
关键说明
- 单元格工厂的
updateItem方法会在表格数据变化、刷新时自动调用,保证每个单元格显示最新计算结果。 - 用
Timeline实现定时更新,避免后台线程操作UI(JavaFX UI操作必须在主线程执行)。 - 新增了过期状态的处理,覆盖边界场景。
内容的提问来源于stack exchange,提问作者Marian34
相关产品推荐
相关产品推荐

