# 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: ```java 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` | `Thread::new` (Daemon) | synchroner Direktaufruf | | `fxDispatcher` | `Consumer` | `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`