Java开发Windows待办事项提醒工具实战

发布时间:2026/9/15 3:34:20
Java开发Windows待办事项提醒工具实战 1. 项目概述基于Java的Windows待办事项提醒工具在Windows平台上开发一个轻量级的待办事项提醒工具使用Java语言和JDK8环境实现。这个工具将帮助用户管理日常任务通过系统托盘图标和弹窗提醒的方式确保重要事项不会被遗忘。不同于复杂的任务管理软件我们聚焦于核心的提醒功能保持简洁高效。2. 核心功能设计2.1 系统托盘集成Java的SystemTray类提供了与操作系统托盘交互的能力。我们需要创建一个托盘图标并为其添加右键菜单// 检查系统是否支持托盘 if (!SystemTray.isSupported()) { System.out.println(SystemTray is not supported); return; } // 获取系统托盘实例 SystemTray tray SystemTray.getSystemTray(); // 创建托盘图标 Image image Toolkit.getDefaultToolkit().getImage(icon.png); TrayIcon trayIcon new TrayIcon(image, 待办事项提醒器); // 设置图标自动调整大小 trayIcon.setImageAutoSize(true); // 创建弹出菜单 PopupMenu popup new PopupMenu(); MenuItem exitItem new MenuItem(退出); exitItem.addActionListener(e - System.exit(0)); popup.add(exitItem); // 添加菜单到托盘图标 trayIcon.setPopupMenu(popup); // 添加托盘图标到系统托盘 try { tray.add(trayIcon); } catch (AWTException e) { System.err.println(无法添加托盘图标: e.getMessage()); }2.2 提醒功能实现使用Timer和TimerTask组合实现定时提醒功能Timer timer new Timer(); TimerTask task new TimerTask() { Override public void run() { // 检查是否有待提醒事项 if (hasReminders()) { // 显示提醒 trayIcon.displayMessage(待办事项提醒, getNextReminder(), TrayIcon.MessageType.INFO); } } }; // 每分钟检查一次 timer.schedule(task, 0, 60 * 1000);3. 数据存储方案3.1 使用SQLite本地数据库为了持久化存储待办事项我们选择轻量级的SQLite数据库// 数据库连接 Connection conn null; try { // 注册JDBC驱动 Class.forName(org.sqlite.JDBC); // 创建数据库连接 conn DriverManager.getConnection(jdbc:sqlite:reminders.db); // 创建表 Statement stmt conn.createStatement(); String sql CREATE TABLE IF NOT EXISTS reminders (id INTEGER PRIMARY KEY AUTOINCREMENT, content TEXT NOT NULL, remind_time DATETIME NOT NULL, is_completed BOOLEAN DEFAULT 0); stmt.executeUpdate(sql); stmt.close(); } catch (Exception e) { System.err.println(e.getClass().getName() : e.getMessage()); } finally { try { if (conn ! null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } }3.2 数据访问层实现封装基本的CRUD操作public class ReminderDAO { private Connection connect() { Connection conn null; try { conn DriverManager.getConnection(jdbc:sqlite:reminders.db); } catch (SQLException e) { System.out.println(e.getMessage()); } return conn; } public void insert(String content, LocalDateTime remindTime) { String sql INSERT INTO reminders(content, remind_time) VALUES(?,?); try (Connection conn this.connect(); PreparedStatement pstmt conn.prepareStatement(sql)) { pstmt.setString(1, content); pstmt.setString(2, remindTime.toString()); pstmt.executeUpdate(); } catch (SQLException e) { System.out.println(e.getMessage()); } } // 其他方法update, delete, query等 }4. 用户界面设计4.1 使用JavaFX创建GUI虽然我们可以使用Swing但JavaFX提供了更现代的UI体验public class ReminderApp extends Application { Override public void start(Stage primaryStage) { // 创建主界面 BorderPane root new BorderPane(); Scene scene new Scene(root, 400, 300); // 添加控件 VBox vbox new VBox(10); TextField contentField new TextField(); DatePicker datePicker new DatePicker(); SpinnerInteger hourSpinner new Spinner(0, 23, 12); SpinnerInteger minuteSpinner new Spinner(0, 59, 0); Button addButton new Button(添加提醒); addButton.setOnAction(e - { LocalDate date datePicker.getValue(); LocalTime time LocalTime.of(hourSpinner.getValue(), minuteSpinner.getValue()); LocalDateTime dateTime LocalDateTime.of(date, time); // 调用DAO添加提醒 new ReminderDAO().insert(contentField.getText(), dateTime); // 清空输入 contentField.clear(); }); vbox.getChildren().addAll( new Label(提醒内容:), contentField, new Label(提醒时间:), new HBox(10, datePicker, hourSpinner, minuteSpinner), addButton ); root.setCenter(vbox); // 设置窗口属性 primaryStage.setTitle(待办事项提醒器); primaryStage.setScene(scene); primaryStage.show(); } }4.2 系统托盘与主界面交互实现托盘图标双击打开主界面功能trayIcon.addActionListener(e - { if (primaryStage.isShowing()) { primaryStage.hide(); } else { primaryStage.show(); primaryStage.toFront(); } });5. 高级功能实现5.1 重复提醒功能扩展数据模型支持重复提醒ALTER TABLE reminders ADD COLUMN repeat_pattern TEXT;实现重复提醒逻辑public boolean shouldRemindNow(Reminder reminder) { LocalDateTime now LocalDateTime.now(); LocalDateTime remindTime reminder.getRemindTime(); if (reminder.getRepeatPattern() null) { // 单次提醒 return now.isAfter(remindTime) !reminder.isCompleted(); } else { // 解析重复模式如DAILY, WEEKLY, MONTHLY switch (reminder.getRepeatPattern()) { case DAILY: return now.toLocalTime().isAfter(remindTime.toLocalTime()) !reminder.isCompleted(); // 其他重复模式... } } return false; }5.2 提醒提前设置允许用户设置提前提醒时间ALTER TABLE reminders ADD COLUMN advance_minutes INTEGER DEFAULT 0;修改提醒检查逻辑public boolean shouldRemindNow(Reminder reminder) { LocalDateTime now LocalDateTime.now(); LocalDateTime remindTime reminder.getRemindTime() .minusMinutes(reminder.getAdvanceMinutes()); // 其余逻辑不变... }6. 打包与部署6.1 使用Launch4j创建EXE虽然Java程序可以直接运行但转换为EXE更符合Windows用户习惯下载Launch4j工具配置基本信息Output file: 输出exe路径Jar: 你的应用程序jar包Icon: 自定义图标设置JRE版本要求为1.8生成EXE文件6.2 Inno Setup创建安装程序制作专业的安装包下载Inno Setup编译器创建脚本文件[Setup] AppName待办事项提醒器 AppVersion1.0 DefaultDirName{pf}\TodoReminder DefaultGroupName待办事项提醒器 OutputDiroutput OutputBaseFilenameTodoReminderSetup Compressionlzma SolidCompressionyes [Files] Source: TodoReminder.exe; DestDir: {app}; Flags: ignoreversion Source: *.dll; DestDir: {app}; Flags: ignoreversion Source: lib\*; DestDir: {app}\lib; Flags: ignoreversion recursesubdirs [Icons] Name: {group}\待办事项提醒器; Filename: {app}\TodoReminder.exe Name: {commondesktop}\待办事项提醒器; Filename: {app}\TodoReminder.exe编译生成安装程序7. 常见问题与解决方案7.1 系统托盘图标不显示可能原因及解决方案图标尺寸问题Windows推荐使用16x16或32x32像素的ICO格式图标权限问题以管理员身份运行程序测试防病毒软件拦截检查安全软件日志7.2 提醒不准确调试步骤检查系统时区设置验证数据库中的时间存储格式确认Timer的调度间隔设置合理7.3 数据库锁定问题多线程访问SQLite时的建议// 使用单例模式管理数据库连接 public class DBConnection { private static Connection instance; public static synchronized Connection getInstance() throws SQLException { if (instance null || instance.isClosed()) { instance DriverManager.getConnection(jdbc:sqlite:reminders.db); // 启用WAL模式提高并发性能 instance.createStatement().execute(PRAGMA journal_modeWAL); } return instance; } }8. 性能优化建议使用连接池管理数据库连接对于大量提醒项实现分页查询优化Timer调度避免频繁唤醒使用缓存减少数据库访问// 使用WeakHashMap缓存最近访问的提醒项 private MapInteger, Reminder cache Collections.synchronizedMap( new WeakHashMapInteger, Reminder()); public Reminder getReminder(int id) { Reminder reminder cache.get(id); if (reminder null) { reminder // 从数据库查询 cache.put(id, reminder); } return reminder; }9. 扩展功能思路云同步通过Web服务实现多设备同步分类标签为待办事项添加分类语音提醒集成TTS引擎手机通知通过推送服务发送到手机数据统计生成完成情况报表实现简单的分类功能示例ALTER TABLE reminders ADD COLUMN category TEXT; // 在UI中添加分类选择 ComboBoxString categoryCombo new ComboBox(); categoryCombo.getItems().addAll(工作, 个人, 家庭, 其他);10. 项目结构建议标准的Maven项目结构todo-reminder/ ├── src/ │ ├── main/ │ │ ├── java/ │ │ │ ├── com/ │ │ │ │ └── example/ │ │ │ │ ├── dao/ │ │ │ │ │ └── ReminderDAO.java │ │ │ │ ├── model/ │ │ │ │ │ └── Reminder.java │ │ │ │ ├── util/ │ │ │ │ │ └── DBUtil.java │ │ │ │ └── MainApp.java │ │ └── resources/ │ │ ├── icon.png │ │ └── styles.css ├── lib/ │ └── sqlite-jdbc-3.36.0.3.jar └── pom.xmlpom.xml关键配置dependencies dependency groupIdorg.xerial/groupId artifactIdsqlite-jdbc/artifactId version3.36.0.3/version /dependency dependency groupIdorg.openjfx/groupId artifactIdjavafx-controls/artifactId version17.0.2/version /dependency /dependencies build plugins plugin groupIdorg.apache.maven.plugins/groupId artifactIdmaven-compiler-plugin/artifactId version3.8.1/version configuration source1.8/source target1.8/target /configuration /plugin plugin groupIdorg.openjfx/groupId artifactIdjavafx-maven-plugin/artifactId version0.0.6/version configuration mainClasscom.example.MainApp/mainClass /configuration /plugin /plugins /build11. 实际开发中的经验分享系统托盘兼容性问题不同Windows版本对托盘图标的支持有差异建议提供备用方案如最小化到任务栏JDK8的日期时间API// 使用Java 8的新日期时间API LocalDateTime now LocalDateTime.now(); DateTimeFormatter formatter DateTimeFormatter.ofPattern(yyyy-MM-dd HH:mm); String formatted now.format(formatter);跨平台考虑 虽然目标是Windows但保持核心逻辑与平台无关// 检查操作系统类型 String os System.getProperty(os.name).toLowerCase(); if (os.contains(win)) { // Windows特定代码 } else { // 其他平台备用方案 }内存管理及时关闭数据库连接使用WeakReference管理大对象注意TimerTask的取消用户数据安全对敏感数据考虑简单加密提供数据备份功能// 简单加密示例 public String encrypt(String input) { // 实际项目中应使用更安全的加密方式 return Base64.getEncoder().encodeToString(input.getBytes()); } public String decrypt(String encrypted) { return new String(Base64.getDecoder().decode(encrypted)); }12. 测试建议单元测试核心逻辑Test public void testShouldRemindNow() { Reminder reminder new Reminder(); reminder.setRemindTime(LocalDateTime.now().plusMinutes(5)); reminder.setAdvanceMinutes(10); assertTrue(reminder.shouldRemindNow()); }UI自动化测试使用TestFX测试JavaFX界面模拟用户操作流程数据库测试测试并发访问验证数据持久化系统集成测试测试从安装到使用的完整流程验证不同Windows版本的兼容性13. 日志记录添加日志记录帮助调试import java.util.logging.Logger; public class MainApp { private static final Logger logger Logger.getLogger(MainApp.class.getName()); public static void main(String[] args) { try { // 初始化代码... logger.info(应用程序启动成功); } catch (Exception e) { logger.severe(启动失败: e.getMessage()); } } }配置logging.properties文件handlers java.util.logging.ConsoleHandler .level INFO java.util.logging.ConsoleHandler.level INFO java.util.logging.ConsoleHandler.formatter java.util.logging.SimpleFormatter java.util.logging.SimpleFormatter.format[%1$tF %1$tT] [%4$-7s] %5$s %n14. 国际化支持为支持多语言使用ResourceBundle// 创建messages.properties // greetingHello // add_reminderAdd Reminder // 创建messages_zh.properties // greeting你好 // add_reminder添加提醒 // 在代码中使用 ResourceBundle bundle ResourceBundle.getBundle(messages, Locale.getDefault()); String greeting bundle.getString(greeting);在JavaFX中绑定国际化文本Label greetingLabel new Label(); greetingLabel.textProperty().bind(Bindings.createStringBinding( () - bundle.getString(greeting), bundle));15. 最终项目优化添加启动画面(Splash Screen)实现自动更新检查添加键盘快捷键支持优化内存占用提供主题切换功能实现简单的主题切换public enum Theme { LIGHT(-fx-base: #ececec;), DARK(-fx-base: #3c3c3c;); private String style; Theme(String style) { this.style style; } public String getStyle() { return style; } } // 切换主题 public void applyTheme(Theme theme) { scene.getRoot().setStyle(theme.getStyle()); }