Files
pdf-umbenenner/docs/architecture/gui-overview.md
T
marcus bdc5e8331f Doku: Modulare Architektur-Dokumentation (#34)
Drei neue Architektur-Übersichten unter docs/architecture/ angelegt
(domain-overview, gui-overview, adapter-overview), die das bisher in
CLAUDE.md verstreute Detailwissen zu Paketen, Schlüsselklassen, Ports
und Bootstrap-Verdrahtung pro Modulbereich bündeln. CLAUDE.md verweist
auf die drei Dateien und enthält das Detailwissen nicht mehr selbst,
sodass Arbeit an einem Modulbereich mit CLAUDE.md plus der jeweils
passenden Übersicht auskommt. Workpackage-Liste um M14 und M15 ergänzt;
V2.9-Implementierungsstand auf Modul-/Verhaltensebene konsolidiert.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 16:21:58 +02:00

11 KiB
Raw Blame History

Architektur-Übersicht: GUI (adapter-in-gui)

Diese Datei beschreibt den Inbound-Adapter pdf-umbenenner-adapter-in-gui die JavaFX-Desktop-GUI des PDF-Umbenenners. Sie ist zusammen mit CLAUDE.md im Projektroot als alleiniger Architekturkontext für GUI-Arbeit gedacht. Domain-Typen, Application-Ports und Outbound-Adapter (Dateisystem, SQLite, KI-HTTP) sind hier bewusst nicht beschrieben; dafür gelten docs/architecture/domain-overview.md und docs/architecture/adapter-overview.md. Das JavaFX-Threading-Modell (Abschnitt 4) ist verbindlich und muss strikt eingehalten werden GUI-Entwickler sollten diesen Abschnitt als erstes lesen.


1. Modulzweck

pdf-umbenenner-adapter-in-gui ist der Inbound-Adapter für die Desktop-Oberfläche. Er:

  • empfängt den Startaufruf von der Bootstrap-Schicht über GuiAdapter,
  • baut das JavaFX-Hauptfenster auf,
  • delegiert alle fachlichen und technischen Operationen an Bootstrap-seitig verdrahtete Ports,
  • zeigt Ergebnisse ausschließlich auf dem JavaFX Application Thread an.

Das Modul enthält keine fachliche Logik, keinen Datenbankzugriff, keinen HTTP-Code und keine PDF-Verarbeitung. Es koordiniert lediglich Benutzereingaben, Worker-Threads und JavaFX-Controls.


2. Paketstruktur

de.gecheckt.pdf.umbenenner.adapter.in.gui
│
├── (root)           Einstiegspunkt, Hauptfenster, Orchestrierung, GUI-interne
│                    Ports, Hilfsklassen für Fenstertitel, System-Tray,
│                    Dateiladen/-schreiben und Startkontext.
│
├── batchrun         Komponenten für den Tab „Verarbeitungslauf":
│                    Worker-Koordinator, Tab-Ansicht, Ergebniszeilen,
│                    PDF-Vorschau, Dateiname-Editor sowie GUI-interne
│                    Port-Interfaces für Batch-Run, Mini-Run, manuelles
│                    Umbenennen/Kopieren, Status-Reset und historischen Kontext.
│
└── editor           View-Modell- und Zustandstypen ohne JavaFX-Controls
                     (Ausnahme: GuiModelFieldContainer). Enthält Snapshot,
                     Baseline/Current-Values, Dirty-State-Berechnung,
                     Provider-Konfigurationszustände, API-Key-Zustände,
                     Validierungsergebnisse, Meldungs- und Feldbefund-Typen.

3. Schlüsselklassen

Root-Paket

Klasse (Kurzname) Rolle
GuiAdapter Einziger öffentlicher Bootstrap-Einstiegspunkt. Speichert GuiStartupContext im GuiStartupContextHolder und startet JavaFX via Application.launch. Genau einmal pro JVM aufrufbar.
PdfUmbenennerGuiApplication JavaFX-Application-Unterklasse. Baut in start(Stage) Hauptfenster, GuiConfigurationEditorWorkspace, Titelaktualisierungs-Listener, Close-Handler und System-Tray auf. Triggert nach Anzeige autoLoadLastConfiguration().
GuiStartupContext Immutable Record mit allen Bootstrap-gelieferten Ports und Services: Dateilader/-schreiber, Modellkatalog-Port, API-Key-Resolution-Port, Technical-Test-Orchestrator, Correction-Execution-Service, Batch-Run-Launcher, Mini-Run-Launcher, Reset-Port, Manual-Rename-Port, Manual-Copy-Port, Historical-Context-Port. Bietet blank()-Fabrikmethode für Tests.
GuiConfigurationEditorWorkspace Herzstück der Oberfläche. Baut TabPane mit Editor-Tab und Verarbeitungslauf-Tab, verwaltet GuiConfigurationEditorState, koordiniert Lade- und Schreibvorgänge auf Worker-Threads, steuert Dirty-State-Anzeige und Fenstertitel.
GuiModelCatalogCoordinator Asynchroner Modellabruf über AiModelCatalogPort auf Daemon-Thread gui-model-catalog. Liefert Ergebnis via Platform.runLater und aktualisiert ComboBox oder manuelles TextField.
GuiTechnicalTestCoordinator Führt TechnicalTestOrchestrator asynchron auf Daemon-Thread gui-technical-test aus, ohne implizites Speichern. Replace-Semantik in pendingMessages.
GuiCorrectionDialogCoordinator Empfängt TechnicalTestReport, leitet CorrectionPlan ab, zeigt gesammelten Bestätigungsdialog. Kein stiller Schreibzugriff.
GuiUnsavedChangesGuard Drei-Wege-Schutzdialog (Speichern / Verwerfen / Abbrechen) vor Neu, Öffnen und Schließen. Dialog-Supplier ist injizierbar für Tests ohne Scene.
SystemTrayManager Verwaltet Windows-System-Tray-Icon. Überbrückt AWT-EDT nach JavaFX via Platform.runLater für Stage-Operationen.

Paket editor

Klasse (Kurzname) Rolle
GuiConfigurationEditorState Record mit loadedFileSnapshot, baselineValues, values, pendingMigrationMessage. Dirty-State wird per Vergleich berechnet, kein Flag.
GuiConfigurationValues Hält alle editierbaren Konfigurationsfelder als JavaFX-freie Plain-Java-Typen.

Paket batchrun

Klasse (Kurzname) Rolle
GuiBatchRunCoordinator Besitzt den Worker-Thread für Batch- und Mini-Run. Übersetzt BatchRunProgressObserver-Callbacks via Platform.runLater. Soft-Stop per AtomicBoolean. Enthält toRow() inkl. historischem Kontext-Nachladen.
GuiBatchRunTab Zweiter Haupt-Tab mit TableView, ProgressBar, Start-/Stop-Buttons und Detailbereich. Implementiert GuiBatchRunCoordinator.Listener.
PdfPreviewPane Asynchrones PDF-Rendering via PDFBox auf Single-Thread-Executor pdf-preview-worker. Stale-Request-Schutz via AtomicLong-Sequenznummer, In-Memory-Seiten-Cache.
FileNameEditorPane Editor für den Zieldateinamen. Drei-Zustands-Modell: KI-Vorschlag / letzter gespeicherter / aktuelle Eingabe. Clientseitige Validierung; Speicher-Aufruf delegiert an Tab.
AiFailureMessageTranslator Übersetzt englische technische Fehlermeldungen in deutsche Benutzertexte. Paket-privat, zustandslos.

4. Threading-Modell

Das Modell ist verbindlich. Jede Verletzung dieser Regeln führt zu sporadischen IllegalStateException-Fehlern oder einer eingefrorenen Oberfläche.

4.1 Worker-Threads

Alle blockierenden Operationen laufen auf benannten Daemon-Threads außerhalb des JavaFX Application Thread.

Thread-Name Koordinator-Klasse Operationen
gui-batch-run GuiBatchRunCoordinator Batch-Launcher, Mini-Run-Launcher, Reset-Port, historischer Kontext
gui-model-catalog GuiModelCatalogCoordinator modelCatalogPort.fetchAvailableModels(...)
gui-technical-test GuiTechnicalTestCoordinator orchestrator.runTests(...)
Korrektur-Worker (anonym) GuiCorrectionDialogCoordinator correctionExecutionService.execute(...)
pdf-preview-worker PdfPreviewPane PDDocument laden, PDFRenderer.renderImageWithDPI, PDDocument.close
Dateisystem-Worker (inline) GuiConfigurationEditorWorkspace configurationFileLoader.load(...), configurationFileWriter.write(...)

4.2 JavaFX Application Thread

Alle Mutationen an JavaFX-Controls und alle Dialoganzeigen ausschließlich auf dem JavaFX Application Thread. Kein direktes Schreiben auf Controls vom Worker-Thread.

4.3 Übergangsmechanismus Worker → FX

Der Übergang erfolgt grundsätzlich via:

Platform.runLater(runnable);

Es werden keine javafx.concurrent.Task und kein Service verwendet. Die Koordinatoren steuern Threading manuell über zwei injizierbare Strategien:

Injektionspunkt Typ Produktion Tests
threadFactory Function<Runnable, Thread> Thread::new (Daemon) synchroner Direktaufruf
fxDispatcher Consumer<Runnable> Platform::runLater synchroner Direktaufruf

Durch diese Injektion sind Unit-Tests vollständig ohne JavaFX-Runtime möglich.

4.4 Stale-Request-Schutz

PdfPreviewPane vergibt für jede Renderanfrage eine inkrementelle AtomicLong-Sequenznummer. Ein abgeschlossenes Render-Ergebnis wird nur dann auf der UI angezeigt, wenn seine Sequenznummer noch der aktuellen entspricht. Veraltete Ergebnisse werden still verworfen.


5. GUI-interne Ports

Abgrenzung: Die folgenden Interfaces sind keine hexagonalen Outbound-Ports der Application-Schicht. Sie sind modul-interne Brücken, über die GuiAdapter die Bootstrap-seitig verdrahteten Implementierungen in die GUI-Klassen einschleust. Die eigentlichen Application-Ports (AiInvocationPort, AiModelCatalogPort usw.) und deren Outbound-Adapter-Implementierungen sind in docs/architecture/domain-overview.md und docs/architecture/adapter-overview.md beschrieben.

Root-Paket

Interface Zweck
GuiConfigurationFileLoader Lädt eine .properties-Datei und liefert einen GuiConfigurationEditorState. Abstrahiert Migration und Bootstrap-Verdrahtung vom GUI-Code.
GuiConfigurationFileWriter Schreibt aktuelle GuiConfigurationValues als normalisierte .properties inkl. Backup-Schema.

Paket batchrun

Interface Zweck
GuiBatchRunLauncher Bootstrap-Brücke für den regulären Batch-Run auf dem Worker-Thread.
GuiMiniRunLauncher Bootstrap-Brücke für einen auf einen Fingerprint-Filter beschränkten Mini-Run.
GuiResetDocumentStatusPort Bootstrap-Brücke für einen Statusreset ohne Folge-Run.
GuiManualFileRenamePort Bootstrap-Brücke für die manuelle Umbenennung der Zieldatei (Worker-Thread).
GuiManualFileCopyPort Bootstrap-Brücke für die Kopie mit benutzerdefiniertem Zieldateinamen bei FAILED/SKIPPED-Dokumenten (Worker-Thread).
GuiHistoricalDocumentContextPort Nachladen des vollständigen historischen Verarbeitungskontexts für übersprungene Dokumente (Worker-Thread).
GuiHistoricalFileNamePort Spezialisierter Port für den letzten bekannten KI-Dateinamen. Weitgehend durch GuiHistoricalDocumentContextPort abgelöst, aber noch im Einsatz.

Alle Implementierungen dieser Interfaces liegen in pdf-umbenenner-bootstrap oder pdf-umbenenner-adapter-out. Das GUI-Modul kennt ausschließlich die Interface-Typen.


6. Einstiegspunkte für neue Entwickler

Folgende Klassen und Dateien decken den schnellsten Einstieg ab:

  1. GuiAdapter Architekturgrenze zur Bootstrap-Schicht in zwei Methoden. Zeigt, wie die GUI aus Bootstrap-Sicht aufgerufen wird.

  2. GuiStartupContext Vollständige Liste aller Ports und Services, die Bootstrap in die GUI injiziert. Wer wissen will, was die GUI von außen bekommt, liest diesen Record.

  3. GuiConfigurationEditorWorkspace Zentrale UI-Klasse: Tab-Aufbau, Sektionen, Editor-Zustand, Dirty-State, Datei-I/O, Sub-Koordinatoren. Einstieg für alle Arbeiten am Konfigurationseditor-Tab.

  4. GuiConfigurationEditorState / GuiConfigurationValues View-Modell ohne JavaFX-Controls. Einstieg für alle Änderungen an editierbaren Konfigurationsfeldern und Dirty-State-Logik.

  5. GuiBatchRunCoordinator Threading-Modell in seiner reinsten Form: Worker-Thread, Platform.runLater-Übergabe, Soft-Stop, Listener-Protokoll. Einstieg für alle Arbeiten am Verarbeitungslauf-Tab.

  6. batchrun/package-info.java Kompakte Beschreibung des Threading-Kontrakts, der Abbruch-Semantik und der Konfigurationsquelle für dieses Paket.

Querverweise

  • Application-Ports und Domain-Typen (NamingProposal, ProcessingStatus, DocumentFingerprint usw.): docs/architecture/domain-overview.md
  • Outbound-Adapter-Implementierungen (Dateisystem, SQLite, KI-HTTP, PDFBox) und Bootstrap-Verdrahtung: docs/architecture/adapter-overview.md