From 8cb56c697fb461d3cbea6ef856156007fc09cc12 Mon Sep 17 00:00:00 2001 From: abedurftig Date: Thu, 15 Jan 2026 22:56:08 +0100 Subject: [PATCH] Fix missing Platform.runLater in event handlers Wrapped all model updates in Platform.runLater() to ensure UI updates happen on the JavaFX Application Thread. Fixed handlers: - handleDocumentTagAddedEvent - handleArchiveEntryAddedEvent - handleLightThemeActivatedSettingsChangedEvent Fixes: smartfiles-vap Co-Authored-By: Claude Opus 4.5 --- .beads/issues.jsonl | 2 +- .../arne/smartfiles/app/ApplicationInteractor.java | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 01ab137..05f466e 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -23,7 +23,7 @@ {"id":"smartfiles-t88","title":"No file type validation on drag and drop","description":"handleDragDropped in ApplicationViewBuilder.java (lines 405-414) passes all dropped files to archiveService.manageFiles() without validating they are PDF files. While DocumentView.viewFile() checks for .pdf extension, the files are already copied to the archive at that point.\n\n**Fix:** Filter files by extension before passing to archive service, or show warning for non-PDF files.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-01-15T22:36:05.469373+01:00","created_by":"abedurftig","updated_at":"2026-01-15T22:36:05.469373+01:00"} {"id":"smartfiles-tre","title":"DateTimeFormatter duplicated across classes","description":"DateTimeFormatter.ofPattern(\"MMM d, yyyy 'at' HH:mm\") is defined identically in both:\n- ApplicationInteractor.java (line 11)\n- AppConfiguration.java (line 13)\n\nThis should be centralized to avoid inconsistency if the format needs to change.\n\n**Fix:** Create a single shared constant or utility class for date formatting.","status":"open","priority":3,"issue_type":"task","created_at":"2026-01-15T22:36:46.434919+01:00","created_by":"abedurftig","updated_at":"2026-01-15T22:36:46.434919+01:00"} {"id":"smartfiles-u4i","title":"Apply consistent tag styling between filter and document views","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-11T21:49:21.617484+01:00","created_by":"abedurftig","updated_at":"2026-01-11T21:53:15.289719+01:00","closed_at":"2026-01-11T21:53:15.289719+01:00","close_reason":"Closed"} -{"id":"smartfiles-vap","title":"Missing Platform.runLater in ApplicationInteractor event handlers","description":"In ApplicationInteractor.java, most event handlers correctly use Platform.runLater() to update the model on the JavaFX Application Thread. However, two handlers do not:\n\n- handleDocumentTagAddedEvent (line 49-51) calls model.updateDocumentTags() directly\n- handleArchiveEntryAddedEvent (line 61-64) calls model.addDocumentFromArchiveEntry() directly\n\nSince Spring events can be published from any thread, these could cause UI updates from non-FX threads, leading to race conditions or crashes.\n\n**Fix:** Wrap these calls in Platform.runLater().","status":"open","priority":1,"issue_type":"bug","created_at":"2026-01-15T22:32:45.051937+01:00","created_by":"abedurftig","updated_at":"2026-01-15T22:32:45.051937+01:00"} +{"id":"smartfiles-vap","title":"Missing Platform.runLater in ApplicationInteractor event handlers","description":"In ApplicationInteractor.java, most event handlers correctly use Platform.runLater() to update the model on the JavaFX Application Thread. However, two handlers do not:\n\n- handleDocumentTagAddedEvent (line 49-51) calls model.updateDocumentTags() directly\n- handleArchiveEntryAddedEvent (line 61-64) calls model.addDocumentFromArchiveEntry() directly\n\nSince Spring events can be published from any thread, these could cause UI updates from non-FX threads, leading to race conditions or crashes.\n\n**Fix:** Wrap these calls in Platform.runLater().","status":"in_progress","priority":1,"issue_type":"bug","created_at":"2026-01-15T22:32:45.051937+01:00","created_by":"abedurftig","updated_at":"2026-01-15T22:55:26.278298+01:00"} {"id":"smartfiles-w73","title":"Maven compiler plugin source/target mismatch","description":"In pom.xml, the properties define java.version=25 and maven.compiler.source/target=25, but the maven-compiler-plugin configuration explicitly sets source=22 and target=22 (lines 129-130), contradicting the properties.\n\n**Fix:** Remove explicit source/target from plugin config to use the property values, or update to match.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-01-15T22:36:17.931659+01:00","created_by":"abedurftig","updated_at":"2026-01-15T22:36:17.931659+01:00"} {"id":"smartfiles-we7","title":"Display document details dateLastModified and dateCreated in the document details","description":"Display the dateCreated and dateLastModified of the selected document in the document details in the bottom right.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-01-07T21:31:02.161058+01:00","created_by":"abedurftig","updated_at":"2026-01-07T21:32:30.284216+01:00"} {"id":"smartfiles-wyr","title":"Window size and position not persisted","description":"The application starts with fixed dimensions (1024x768) and does not save/restore window size or position. This is a user experience issue as preferences are lost on restart.\n\n**File:** SmartFilesApp.java (lines 22-23)\n\n**Fix:** Save window bounds to settings on close, restore on startup.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-01-15T22:37:37.871391+01:00","created_by":"abedurftig","updated_at":"2026-01-15T22:37:37.871391+01:00"} diff --git a/src/main/java/dev/arne/smartfiles/app/ApplicationInteractor.java b/src/main/java/dev/arne/smartfiles/app/ApplicationInteractor.java index 9ba3f50..cc9710b 100644 --- a/src/main/java/dev/arne/smartfiles/app/ApplicationInteractor.java +++ b/src/main/java/dev/arne/smartfiles/app/ApplicationInteractor.java @@ -47,19 +47,18 @@ private void handleTagAddedEvent(TagAddedEvent e) { } private void handleDocumentTagAddedEvent(DocumentTagAddedEvent e) { - model.updateDocumentTags(); + Platform.runLater(() -> model.updateDocumentTags()); } private void handleDocumentDescriptionUpdatedEvent(DocumentDescriptionUpdatedEvent e) { Platform.runLater(() -> model.updateDescription(e.getDescription())); } - private void handleLightThemeActivatedSettingsChangedEvent(LightThemeActivatedSettingChangedEvent lightThemeActivatedSettingChangedEvent) { - model.setLightModeActivated(lightThemeActivatedSettingChangedEvent.isLightThemeActive()); + private void handleLightThemeActivatedSettingsChangedEvent(LightThemeActivatedSettingChangedEvent e) { + Platform.runLater(() -> model.setLightModeActivated(e.isLightThemeActive())); } - private void handleArchiveEntryAddedEvent(ArchiveEntryAddedEvent event) { - var entry = event.getArchiveEntry(); - model.addDocumentFromArchiveEntry(entry); + private void handleArchiveEntryAddedEvent(ArchiveEntryAddedEvent e) { + Platform.runLater(() -> model.addDocumentFromArchiveEntry(e.getArchiveEntry())); } }