From 0651fcb6ebad698fc8530af1cbf265cbaf92552f Mon Sep 17 00:00:00 2001 From: Marcus van Elst Date: Tue, 5 May 2026 15:51:35 +0200 Subject: [PATCH] Fange JavaFX-Reset von hvalue mit ChangeListener ab statt per Timing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Beim Verlassen des Fit-Modus resettet JavaFX hvalue mehrfach auf 0.0, auch nach unserem Platform.runLater-Aufruf. Verschachtelte runLater können diesen Reset nicht zuverlässig überholen. Lösung: Single-Shot-ChangeListener auf hvalueProperty. Er feuert beim Reset, entfernt sich selbst und postet erst dann setHvalue(0.5)/ setVvalue(0.5) – garantiert nach dem Reset, ohne Timing-Annahmen. Folge-Zoom-Schritte (wasInFitMode == false) bleiben unverändert mit einfachem runLater. Co-Authored-By: Claude Sonnet 4.6 --- .../in/gui/batchrun/PdfPreviewPane.java | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/PdfPreviewPane.java b/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/PdfPreviewPane.java index 3eb9644..1ac5b0a 100644 --- a/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/PdfPreviewPane.java +++ b/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/PdfPreviewPane.java @@ -18,6 +18,7 @@ import org.apache.pdfbox.rendering.ImageType; import org.apache.pdfbox.rendering.PDFRenderer; import javafx.application.Platform; +import javafx.beans.value.ChangeListener; import javafx.embed.swing.SwingFXUtils; import javafx.geometry.Bounds; import javafx.geometry.Insets; @@ -727,20 +728,25 @@ public final class PdfPreviewPane { imageView.setFitHeight(0); if (wasInFitMode) { - // Erster Zoom-Schritt nach Verlassen des Fit-Modus: doppelt - // verschachteltes runLater. Das erste runLater stößt den Layout-Pass - // nach setFitToWidth(false) an; das zweite feuert im darauffolgenden - // Pulse, wenn alle Layout-Folgen abgeschlossen sind. Andernfalls - // überschreibt der system-bedingte H/V-Reset auf 0.0 (ausgelöst durch - // setFitToWidth(false)) den setHvalue(0.5)-Aufruf, und die PDF - // springt links/oben bündig statt zentriert zu erscheinen. - Platform.runLater(() -> { - scrollPane.layout(); + // Erster Zoom-Schritt nach Verlassen des Fit-Modus: setFitToWidth(false) + // löst einen system-bedingten Reset von hvalue auf 0.0 aus. Statt + // diesen Reset per Timing zu umgehen (was nicht zuverlässig ist), + // wird er aktiv abgefangen: Ein einmaliger ChangeListener auf + // hvalueProperty feuert beim Reset, entfernt sich sofort selbst + // (Single-Shot) und postet anschließend die Zentrierung via + // Platform.runLater. So wirkt setHvalue(0.5)/setVvalue(0.5) + // garantiert nach dem Reset – ohne mehrfaches runLater oder + // layout()-Hacks. + @SuppressWarnings("unchecked") + final ChangeListener[] holder = new ChangeListener[1]; + holder[0] = (obs, oldVal, newVal) -> { + scrollPane.hvalueProperty().removeListener(holder[0]); Platform.runLater(() -> { scrollPane.setHvalue(0.5); scrollPane.setVvalue(0.5); }); - }); + }; + scrollPane.hvalueProperty().addListener(holder[0]); } else { // Folge-Schritte: aktuelle Scroll-Position bewahren double hval = scrollPane.getHvalue();