选用JavaFX而非Swing因后者样式陈旧且UI线程交互易抛IllegalStateException;JavaFX提供Timeline、Alert及绑定控件,更适配提醒闭环,需用Platform.runLater更新UI、ScheduledExecutorService管理定时任务、ObservableList实现自动刷新。
为什么不用 Swing 而选 JavaFX 来做提醒工具界面
Swing 组件默认样式陈旧,Timer 和线程调度与 UI 交互容易出 IllegalStateException: Not on FX application thread 错误;JavaFX 提供原生的 Timeline、Alert 和绑定式控件(如 ObservableList),更适合实现「添加事项→设置时间→到点弹窗提醒」这个闭环。初学者若硬套 Swing,大概率会在 SwingUtilities.invokeLater 和 Timer 嵌套里迷失。
实操建议:
- 用
javafx.application.Application启动,别写main里直接 new Frame - 所有 UI 更新(比如在列表加一条新事项)必须走
Platform.runLater() - 提醒触发逻辑不要放在
Button.setOnAction里直接 sleep —— 那会卡死整个界面
如何让提醒准时触发且不重复弹窗
核心是用 ScheduledExecutorService 管理定时任务,而不是轮询或 Thread.sleep。每个提醒事项对应一个 ScheduledFuture,保存在 Map 中,方便取消或替换。
常见错误现象:同一事项点了两次“添加”,结果到点弹两个一模一样的 Alert。
实操建议:
- 给每条事项生成唯一 ID(例如
UUID.randomUUID().toString()),作为 map 的 key - 添加前先检查该 ID 是否已存在,存在则调用
future.ca再新建
ncel(true) - 触发时用
Alert alert = new Alert(AlertType.INFORMATION),设alert.setHeaderText(null)避免默认标题干扰 - 务必调用
alert.showAndWait()而非show(),否则用户还没点确认,后续提醒可能叠加
数据怎么存?别急着上 SQLite 或 JSON 文件
初学者项目目标是跑通流程,不是造轮子。内存存储 + 序列化到本地文件(如 reminders.ser)足够用,且避免引入 JDBC 或 Jackson 依赖带来的配置和异常处理负担。
使用场景:关闭程序再打开,上次添加的事项还在列表里。
实操建议:
- 定义类时加上
implements Serializable,字段用private static final long serialVersionUID = 1L - 读写用
ObjectOutputStream/ObjectInputStream,路径固定为"./reminders.ser" - 捕获
IOException和ClassNotFoundException,失败时清空列表并 log,别让程序崩溃 - 不要在 JavaFX 主线程里做文件 IO —— 用
Executors.newCachedThreadPool()异步读写
为什么点击“删除”后列表没刷新
因为直接操作了 ArrayList,但 JavaFX 的 ListView 绑定的是 ObservableList。改底层数据源却不通知 UI,等于白删。
典型错误代码:
items.remove(selectedItem); // items 是 ArrayList
实操建议:
- 初始化时用
FXCollections.observableArrayList()创建列表 - 绑定到 ListView:
listView.setItems(observableItems);
- 删除时调用
observableItems.remove(selectedItem),自动触发 UI 更新 - 如果要支持多选删除,用
listView.getSelectionModel().getSelectedItems()获取 ObservableList 视图,再批量 remove

ncel(true)






