18 KiB
V2.9 – Integrierte PDF-Vorschau und Dateinamen-Bearbeitung
Status: Freigegeben Erstellt: 2026-04-24 Überarbeitet: 2026-04-24 (nach zwei ChatGPT-Reviews, finale Version) Autor: Marcus (mit Claude als Mentor)
Ziel
V2.9 erweitert den Tab „Verarbeitungslauf" um zwei eng verzahnte Funktionen:
- Integrierte PDF-Vorschau – beim Anklicken einer Zeile wird die erste Seite der Quelldatei direkt im Detailbereich rechts gerendert (kein separates Fenster, kein zusätzlicher Klick)
- Editierbarer Dateiname – der von der KI vorgeschlagene Dateiname kann direkt in der GUI korrigiert werden, bevor er als endgültig gilt
Beide Funktionen zusammen ermöglichen einen natürlichen Review-Zyklus: KI benennt → Benutzer schaut rein → Benutzer korrigiert bei Bedarf → fertig.
Hintergrund
Bisheriger Zustand
- Der Detailbereich rechts zeigt nur KI-Begründung als TextArea
- Ob der vorgeschlagene Dateiname sinnvoll ist, kann der Benutzer nur anhand des KI-Reasonings beurteilen – den tatsächlichen Dokumentinhalt sieht er nicht
- Der generierte Dateiname ist nach dem Lauf nicht mehr veränderbar
- Die Spike-Implementierung (PDFViewFX + jai-imageio-jpeg2000 für JBIG2-Unterstützung) hat die technische Machbarkeit bereits bestätigt; der Spike-Code wird im Rahmen von V2.9 durch produktionsreifen Code ersetzt
Motivation
- Benutzer sollen schnell beurteilen können, ob der KI-Dateiname passt, ohne ein externes Programm öffnen zu müssen
- Korrekturen sollen direkt in der Anwendung möglich sein – für nicht-technische Benutzer (z. B. Familienmitglieder) ist das eine wesentliche UX-Verbesserung
- Die Anwendung wird vom reinen Batch-Prozessor zum assistierten Dokumenten-Review-Werkzeug weiterentwickelt
Zielbild
Nach Abschluss von V2.9 kann der Benutzer:
- Eine Zeile in der Ergebnisliste anklicken
- Sofort die erste Seite der zugehörigen Quelldatei als Vorschau sehen – ohne weiteren Klick, direkt im Detailbereich
- Weitere Seiten bei Bedarf auf Anfrage laden (Lazy Rendering)
- Den vorgeschlagenen Dateinamen direkt in der GUI bearbeiten und speichern
- Den headless-Betrieb unverändert nutzen – V2.9 betrifft ausschließlich die GUI
Layout-Änderung im Tab „Verarbeitungslauf"
Bisheriges Layout
[ Fortschrittsbalken ]
[ Ergebnistabelle (~75% Breite) | KI-Begründung (~25%) ]
[ Buttons ]
[ Statuszeile ]
Neues Layout
[ Fortschrittsbalken ]
[ Ergebnistabelle (~60% Breite) | Detailbereich (~40% Breite) ]
[ | KI-Begründung ]
[ | Dateiname (editierbar) ]
[ | PDF-Vorschau (Seite X/Y) ]
[ Buttons ]
[ Statuszeile ]
- Tabelle und Detailbereich sind durch einen verschiebbaren Splitter (SplitPane) getrennt – der Benutzer kann das Verhältnis anpassen
- Standard-Split: 60% Tabelle / 40% Detailbereich
- Der Detailbereich ist vertikal aufgebaut: KI-Begründung oben (kompakt), darunter Dateiname-Feld, darunter PDF-Vorschau (nimmt verfügbaren Restplatz)
- Die PDF-Vorschau rendert die erste Seite „fit to width" – Seitenverhältnis wird beibehalten, die Seite füllt die verfügbare Panelbreite aus
Fachliche Anforderungen
PDF-Vorschau
Grundverhalten
- Beim Anklicken einer Zeile in der Ergebnisliste wird automatisch Seite 1 der zugehörigen Quelldatei gerendert und im Vorschaubereich angezeigt
- Das Rendering erfolgt asynchron im Hintergrund – die GUI bleibt während des Ladens reaktionsfähig
- Während des Renderings wird ein Ladeindikator (z. B. ProgressIndicator) angezeigt
- Die Vorschau zeigt immer die Quelldatei, nicht die umbenannte Zieldatei
Lazy Rendering und Seitennavigation
- Beim ersten Anklicken einer Zeile wird ausschließlich Seite 1 gerendert
- Unterhalb der Vorschau wird die aktuelle Seite sowie die Gesamtseitenzahl angezeigt: „Seite 1 / 12"
- Navigation:
- Button „Nächste Seite" lädt und rendert die jeweils nächste Seite on-demand
- Button „Vorherige Seite" lädt die vorherige Seite
- Bereits gerenderte Seiten werden gecacht – ein erneuter Wechsel auf eine bereits gerenderte Seite erfordert kein erneutes Rendering
- Der Cache wird geleert wenn eine andere Zeile angeklickt wird
- Die Navigations-Buttons sind bei Seite 1 (Zurück) bzw. letzter Seite (Weiter) deaktiviert
Abbruchverhalten bei schnellem Wechsel (Latest Preview Request Wins)
- Es gilt das Prinzip „latest preview request wins": Wenn während eines laufenden Renderings eine neue Vorschau-Anforderung eingeht – sei es durch Selektionswechsel oder durch Seitennavigation innerhalb derselben PDF – wird das laufende Rendering abgebrochen bzw. sein Ergebnis verworfen
- Nur das Ergebnis der zuletzt angeforderten Vorschau darf im Vorschaubereich landen
- Veraltete Render-Ergebnisse werden niemals angezeigt
Fehlerfälle PDF-Vorschau
| Situation | Verhalten |
|---|---|
| Quelldatei nicht mehr vorhanden | Meldung im Vorschaubereich: „Quelldatei nicht gefunden" |
| PDF nicht lesbar / korrupt | Meldung im Vorschaubereich: „PDF konnte nicht geöffnet werden" |
| PDF passwortgeschützt / verschlüsselt | Meldung im Vorschaubereich: „PDF ist passwortgeschützt und kann nicht angezeigt werden" |
| JBIG2-Bilder nicht vollständig dekodierbar | Seite wird teilweise gerendert; kein Fehler-Abbruch; kein Hinweis nötig |
| Kein Eintrag selektiert | Vorschaubereich zeigt neutralen Platzhaltertext |
Technische Grundlage
- Bibliothek:
com.dlsc.pdfviewfx:pdfviewfx(bereits im Spike erfolgreich getestet) - Zusatzabhängigkeit für JBIG2 und erweiterte Bildformate:
com.github.jai-imageio:jai-imageio-jpeg2000(bereits im Spike ergänzt) - Der Spike-Code (
PdfViewerSpike.java, Spike-Button inGuiBatchRunTab) wird vollständig entfernt und durch die produktive Implementierung ersetzt - Rendering läuft in einem dedizierten Background-Thread (nicht im JavaFX Application Thread)
Editierbarer Dateiname
Zustandsmodell
Der Dateiname-Bereich kennt drei klar getrennte Zustände:
| Zustand | Beschreibung |
|---|---|
| KI-Vorschlag | Der von der KI ursprünglich generierte Name – unveränderlich in der DB gespeichert; dient als Referenz für „Zurücksetzen auf KI-Vorschlag" |
| Letzter gespeicherter Name | Der zuletzt per „Dateiname übernehmen" bestätigte Name (= aktueller FS- und DB-Stand); ist nach dem Batch-Lauf zunächst identisch mit dem KI-Vorschlag |
| Aktuelle Eingabe | Der aktuell im Textfeld eingetippte, noch nicht gespeicherte Wert |
Anzeige-Regel: Im Textfeld wird beim Selektieren einer Zeile immer der letzte gespeicherte Name angezeigt – nicht der KI-Vorschlag. Wurde noch nie manuell gespeichert, sind beide identisch.
Dirty-State-Regel: Dirty-State besteht wenn die aktuelle Eingabe vom letzten gespeicherten Namen abweicht. Der KI-Vorschlag ist keine Dirty-Basis.
Anzeige
- Unterhalb der KI-Begründung und oberhalb der PDF-Vorschau befindet sich ein Bereich „Dateiname"
- Der Dateiname wird in einem editierbaren Textfeld (TextField) angezeigt
- Das Textfeld zeigt den letzten gespeicherten Namen ohne Dateierweiterung
(
.pdfwird separat als nicht editierbares Label daneben angezeigt) - Solange kein Eintrag selektiert ist, ist das Textfeld leer und deaktiviert
- Wenn das Textfeld vom letzten gespeicherten Namen abweicht (Dirty State), wird dies durch eine visuelle Markierung am Textfeld angezeigt (z. B. farbiger Rand)
Tastatur- und Schaltflächen-Verhalten
| Aktion | Verhalten |
|---|---|
| Enter im Textfeld | Löst „Dateiname übernehmen" aus (sofern Validierung grün) |
| Escape im Textfeld | Verwirft aktuelle Eingabe; stellt letzten gespeicherten Namen wieder her |
| „Dateiname übernehmen" | Startet die atomare Speicher-Transaktion |
| „Zurücksetzen auf KI-Vorschlag" | Setzt das Textfeld auf den ursprünglichen KI-Vorschlag zurück (kein Speichern – nur Textfeld-Inhalt) |
Hinweis: „Zurücksetzen auf KI-Vorschlag" und Escape haben unterschiedliche Semantik: Escape = zurück zum letzten gespeicherten Stand; „Zurücksetzen" = zurück zum KI-Ursprung.
Speichern-Transaktion (Alles oder Nichts)
Das Speichern eines geänderten Dateinamens ist eine atomare Operation bestehend aus zwei Persistenzschritten:
- Zieldatei im Dateisystem umbenennen
- Eintrag in der SQLite-DB aktualisieren
Schlägt Schritt 1 oder 2 fehl, wird die gesamte Aktion abgebrochen:
- Bereits durchgeführte Teilschritte werden zurückgerollt
- Dateisystem und DB bleiben im vorherigen Zustand
- Eine Fehlermeldung im Statusbereich informiert den Benutzer
- Das Textfeld behält den eingegebenen Wert – der Benutzer kann es erneut versuchen
Nach erfolgreicher Transaktion (Projektionsschritt, nicht Teil der Transaktion):
- Tabellenspalte „Neuer Dateiname" wird aktualisiert
- Erfolgsmeldung im Statusbereich
Mögliche Fehlerursachen für Schritt 1: Datei-Lock durch andere Prozesse (Scanner, AV), fehlende Schreibrechte, Read-only-Dateisystem, Netzlaufwerk nicht erreichbar.
Konfliktsemantik bei vorhandenem Zieldateinamen
Existiert im Zielordner bereits eine Datei mit dem neu eingegebenen Namen, wird anhand des Fingerprints (SHA-256 des Dateiinhalts) entschieden:
| Situation | Verhalten |
|---|---|
| Gleicher Fingerprint | Dateien sind inhaltlich identisch → keine Aktion; Meldung im Statusbereich: „Identische Datei bereits vorhanden – keine Umbenennung nötig"; weder FS noch DB werden geändert |
| Unterschiedlicher Fingerprint | Warnung im Statusbereich; Dateiname im FS erhält automatisch ein Suffix (1), (2) usw.; DB wird mit dem tatsächlichen neuen Namen inkl. Suffix aktualisiert |
Validierung des Dateinamens
Folgende Prüfungen erfolgen live während der Eingabe:
| Prüfung | Verhalten bei Verletzung |
|---|---|
| Dateiname ist leer oder nur Leerzeichen | Speichern-Button deaktiviert, Hinweistext unterhalb des Feldes |
| Führende oder abschließende Leerzeichen | Speichern-Button deaktiviert, Hinweistext |
Unerlaubte Zeichen (\ / : * ? " < > |) |
Speichern-Button deaktiviert, Hinweistext |
Reservierte Windows-Namen (CON, PRN, AUX, NUL, COM1–COM9, LPT1–LPT9) |
Speichern-Button deaktiviert, Hinweistext |
| Dateiname endet auf Punkt | Speichern-Button deaktiviert, Hinweistext |
Dateiname + Zielpfad + .pdf überschreitet 259 Zeichen |
Speichern-Button deaktiviert, Hinweistext |
Die 259-Zeichen-Grenze ist eine bewusste Produktregel für maximale Windows-Kompatibilität (Windows MAX_PATH = 260 Zeichen inkl. Null-Terminator).
Zustände des Dateiname-Bereichs
| Zeilenstatus | Verhalten |
|---|---|
| Kein Eintrag selektiert | Textfeld leer, deaktiviert |
Eintrag mit Status DONE (erfolgreich) |
Textfeld editierbar, letzter gespeicherter Name vorausgefüllt |
Eintrag mit Status FAILED_* |
Textfeld leer, deaktiviert (kein Dateiname vorhanden) |
Eintrag mit Status SKIPPED |
Textfeld deaktiviert |
| Lauf aktiv | Textfeld deaktiviert, alle Buttons deaktiviert |
Verhalten bei fehlender Zieldatei
Ist die Zieldatei zum Zeitpunkt des Speicherns nicht mehr im Zielordner vorhanden:
- Schritt 1 der Transaktion schlägt fehl
- Gemäß Alles-oder-Nichts-Prinzip: DB wird nicht aktualisiert
- Fehlermeldung im Statusbereich: „Zieldatei nicht gefunden – Umbenennung nicht möglich"
- Das Textfeld behält den eingegebenen Wert
Verhalten bei ungespeicherten Änderungen (Dirty State)
Ein Hinweisdialog erscheint, wenn der Benutzer mit aktivem Dirty-State eine der folgenden Aktionen ausführt:
- Eine andere Zeile in der Ergebnistabelle anklicken
- Den Tab wechseln (Konfiguration ↔ Verarbeitungslauf)
- Die Anwendung schließen
- Einen neuen Lauf starten
Dialog-Text: „Der Dateiname wurde geändert aber nicht gespeichert. Änderungen verwerfen?" Optionen: „Verwerfen" (Dirty State wird geleert, Aktion wird fortgesetzt) / „Zurück" (Dialog schließt, Benutzer bleibt im Textfeld)
Architektur
Manuelle Namenskorrektur als Application-Use-Case
Die manuelle Dateinamen-Korrektur wird als eigenständiger Application-Use-Case modelliert, nicht im GUI-Adapter implementiert:
- Ein neuer Use-Case
ManualFileRenameUseCase(o. ä.) kapselt die atomare Transaktion aus FS-Rename + DB-Update - Der
GuiBatchRunCoordinator(GUI-Adapter) delegiert ausschließlich an diesen Use-Case - Dateisystem- und DB-Zugriffe laufen ausschließlich über bestehende oder neue Ports/Adapter – kein Direktzugriff aus dem GUI-Adapter
- Damit bleibt die hexagonale Architektur gewahrt und der Use-Case ist unabhängig von der GUI testbar
Komponenten-Übersicht
| Komponente | Änderung |
|---|---|
GuiBatchRunTab |
Hauptumbau: SplitPane, Detailbereich-Redesign, Spike-Code entfernen |
GuiBatchRunResultRow |
Neues Feld: correctedFileName als Optional<String> |
GuiBatchRunCoordinator |
Delegiert Dateinamen-Korrektur an neuen Use-Case |
ManualFileRenameUseCase |
Neuer Application-Use-Case: atomares FS-Rename + DB-Update |
pom.xml (GUI-Modul) |
PDFViewFX + jai-imageio-jpeg2000 bleiben; Spike-Klasse entfernen |
| Domain / Ports | Ggf. neuer Port für Datei-Rename-Operation erforderlich |
| Headless-Betrieb | Unberührt |
Abhängigkeiten zwischen den Funktionen
- PDF-Vorschau und editierbarer Dateiname sind unabhängig voneinander nutzbar
- Beide beziehen sich auf den in der Ergebnistabelle selektierten Eintrag
- Beim Selektionswechsel mit Dirty-State: Hinweisdialog erscheint (siehe oben)
- PDF-Vorschau-Cache wird beim Selektionswechsel geleert
Verhalten während eines laufenden Batch-Laufs
- Der Detailbereich (PDF-Vorschau + Dateinamen-Editor) ist vollständig deaktiviert während ein regulärer Lauf oder Mini-Lauf aktiv ist
- Bereits angezeigte Vorschau bleibt sichtbar, aber Navigation und Bearbeitung sind gesperrt
Nicht in V2.9 enthalten
- Löschen der Quelldatei nach Bestätigung (spätere Version)
- Vollständiger PDF-Viewer mit freiem Scrollen und Zoom (Issue #23: DPI-Optimierung)
- Historien-Tab / SQLite-Ansicht (Issue #7, V3.0)
- Automatischer Scheduler / System-Tray (Issues #20, #22)
- Kompakteres Layout der Konfigurationsseite (Issue #24)
- Anwendungs-Icon (Issue #21)
Abnahmekriterien
Fachliche Akzeptanz
PDF-Vorschau
- Beim Anklicken einer Zeile wird Seite 1 der Quelldatei automatisch gerendert – ohne extra Klick
- Während des Renderings ist ein Ladeindikator sichtbar; die GUI bleibt reaktionsfähig
- Die Vorschau rendert „fit to width" mit beibehaltenem Seitenverhältnis
- Seitenanzahl wird angezeigt: „Seite 1 / X"
- „Nächste Seite" / „Vorherige Seite" laden Seiten on-demand
- Bereits gerenderte Seiten werden gecacht; Selektionswechsel leert den Cache
- Navigations-Buttons sind korrekt deaktiviert (erste / letzte Seite)
- Schneller Selektionswechsel oder Seitenwechsel während Rendering: nur das zuletzt angeforderte Ergebnis wird angezeigt (latest preview request wins)
- Quelldatei nicht vorhanden → verständliche Fehlermeldung im Vorschaubereich
- PDF nicht lesbar / korrupt → verständliche Fehlermeldung im Vorschaubereich
- PDF passwortgeschützt → verständliche Fehlermeldung im Vorschaubereich
Dateiname-Editor
- Textfeld zeigt beim Selektieren den letzten gespeicherten Namen (nicht KI-Vorschlag) ohne
.pdf-Erweiterung;.pdfals nicht editierbares Label daneben sichtbar - Dateiname ist direkt im Textfeld editierbar
- Dirty-State (Abweichung von letztem gespeichertem Namen) wird visuell am Textfeld angezeigt
- Enter im Textfeld löst „Dateiname übernehmen" aus (wenn Validierung grün)
- Escape im Textfeld stellt den letzten gespeicherten Namen wieder her
- „Zurücksetzen auf KI-Vorschlag" setzt das Textfeld auf den KI-Ursprung zurück (ohne Speichern)
- Validierung prüft live: leer/nur Leerzeichen, führende/abschließende Leerzeichen, unerlaubte Zeichen, reservierte Windows-Namen, endet auf Punkt, Pfadlänge > 259
- Bei Validierungsfehler: Speichern-Button deaktiviert, Hinweistext sichtbar
- „Dateiname übernehmen" ist atomar: FS und DB werden beide aktualisiert oder nichts davon
- Bei Fehler in FS oder DB: kein Teilupdate, Rollback, Fehlermeldung im Statusbereich, Textfeld behält Eingabe
- Nach Erfolg: Tabellenspalte und Statusbereich aktualisiert (Projektionsschritt)
- Dateikonflikt mit gleichem Fingerprint → keine Aktion, Meldung „Identische Datei bereits vorhanden"
- Dateikonflikt mit unterschiedlichem Fingerprint → Warnung, Suffix
(1)usw., DB mit tatsächlichem Namen - Zieldatei fehlt → Fehlermeldung, weder FS noch DB werden geändert
- Ungespeicherte Änderungen bei Selektionswechsel → Hinweisdialog erscheint
- Ungespeicherte Änderungen bei Tabwechsel → Hinweisdialog erscheint
- Ungespeicherte Änderungen beim App-Schließen → Hinweisdialog erscheint
- Ungespeicherte Änderungen bei Laufstart → Hinweisdialog erscheint
- Status
FAILED_*undSKIPPED→ Dateiname-Textfeld deaktiviert - Während eines aktiven Laufs: Detailbereich vollständig deaktiviert
Technische DoD
- Spike-Button und
PdfViewerSpike.javasind vollständig entfernt - Tab „Verarbeitungslauf" zeigt Tabelle und Detailbereich nebeneinander (SplitPane, 60/40, verschiebbar)
ManualFileRenameUseCaseist im Application-Modul implementiert und unabhängig von der GUI testbar- headless-Betrieb ist unverändert funktionsfähig
mvn clean verifyist grün