diff --git a/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/history/GuiHistoryTab.java b/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/history/GuiHistoryTab.java index 8b5260c..abcf6fc 100644 --- a/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/history/GuiHistoryTab.java +++ b/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/history/GuiHistoryTab.java @@ -25,7 +25,9 @@ import de.gecheckt.pdf.umbenenner.application.usecase.DefaultHistoryDetailsUseCa import de.gecheckt.pdf.umbenenner.application.usecase.DefaultHistoryOverviewUseCase.HistoryOverviewResult; import de.gecheckt.pdf.umbenenner.domain.model.DocumentFingerprint; import de.gecheckt.pdf.umbenenner.domain.model.ProcessingStatus; +import javafx.animation.PauseTransition; import javafx.application.Platform; +import javafx.util.Duration; import javafx.util.StringConverter; import javafx.beans.property.SimpleStringProperty; import javafx.collections.FXCollections; @@ -60,6 +62,7 @@ import javafx.scene.layout.VBox; * Zeigt alle jemals verarbeiteten Dokumente aus der SQLite-Datenbank in einer * zweispaltigen Ansicht: links eine filterbare Dokumentenliste (~55%), * rechts ein Detailbereich mit Stammsatz, Versuchstabelle und KI-Begründung (~45%). + * Das Suchfeld ist mit einem 300-ms-Debounce ausgestattet (Live-Filter). * *

Layout

*
@@ -139,6 +142,12 @@ public final class GuiHistoryTab {
     // ---- Zustand --------------------------------------------------------
     private final ExecutorService workerPool;
 
+    /**
+     * Debounce-Timer für das Suchfeld: löst {@link #loadOverview()} aus, sobald
+     * 300 ms nach der letzten Texteingabe vergangen sind.
+     */
+    private final PauseTransition searchDebounce = new PauseTransition(Duration.millis(300));
+
     /**
      * Erzeugt den Historien-Tab.
      *
@@ -462,9 +471,11 @@ public final class GuiHistoryTab {
     private void wireEvents() {
         refreshButton.setOnAction(e -> loadOverview());
 
-        // Debounce-artige Aktualisierung bei Texteingabe: direkte Suche bei Enter,
-        // sonst über Fokus-Verlust oder expliziten Aktualisieren-Button
-        searchField.setOnAction(e -> loadOverview());
+        // Live-Filter: 300-ms-Debounce bei jeder Texteingabe
+        searchDebounce.setOnFinished(e -> loadOverview());
+        searchField.textProperty().addListener((obs, old, val) -> searchDebounce.playFromStart());
+        // Enter-Taste: sofort suchen, Debounce-Timer stoppen
+        searchField.setOnAction(e -> { searchDebounce.stop(); loadOverview(); });
 
         statusFilterBox.setOnAction(e -> loadOverview());