#82: Live-Filter im Verlauf-Tab mit 300-ms-Debounce

Das Suchfeld löst loadOverview() nach 300 ms Tippinaktivität automatisch aus
(PauseTransition). Enter-Taste stoppt den Timer und sucht sofort. So wird die
Tabelle live gefiltert, ohne bei jedem Tastendruck eine DB-Anfrage zu starten.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-05 12:35:30 +02:00
parent beade6ba2e
commit 9f222208c0
@@ -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).
*
* <h2>Layout</h2>
* <pre>
@@ -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());