From 3fb511601cbdf2940b55b3fef0cc884cc2158730 Mon Sep 17 00:00:00 2001 From: Marcus van Elst Date: Tue, 5 May 2026 15:26:31 +0200 Subject: [PATCH] =?UTF-8?q?Korrigiere=20Reihenfolge=20in=20resetToFitView?= =?UTF-8?q?=20f=C3=BCr=20zuverl=C3=A4ssige=20Zentrierung?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Zwei zusammenwirkende Ursachen für die linksbündige Anzeige nach Zoom-Reset: 1. Die Property-Bindungen wurden vor setFitToWidth(true) gesetzt. Zu diesem Zeitpunkt sizet der viewStack noch nach der zoom-großen ImageView, sodass die Bindungen die imageView an die Zoom-Breite gekoppelt haben statt an die Viewport-Breite. 2. Verbleibende H/V-Werte aus Pan-/Zoom-Modus (insbesondere hvalue=0.0 nach Pan zum linken Rand) wurden nicht zurückgesetzt. Bei minimalsten Rounding-/Border-Differenzen wirkt hvalue auch im fit-aktiven Modus und richtet den Content links bündig aus. Fix: setFitToWidth/Height(true) sofort; Bindings und setHvalue(0.5)/ setVvalue(0.5) im Platform.runLater nach abgeschlossenem Layout-Pass. Co-Authored-By: Claude Sonnet 4.6 --- .../in/gui/batchrun/PdfPreviewPane.java | 34 ++++++++++++++----- 1 file changed, 25 insertions(+), 9 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 4786780..f81a212 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 @@ -743,13 +743,20 @@ public final class PdfPreviewPane { * Setzt Zoom, Akkumulator und Pan-Zustand zurück und reaktiviert den Fit-to-View-Modus. * Wird beim Laden einer neuen Datei und beim Leeren der Komponente aufgerufen. * - *

Die Property-Bindungen von {@code fitWidth}/{@code fitHeight} an - * {@code viewStack.widthProperty()}/{@code viewStack.heightProperty()} werden - * wiederhergestellt – damit ist der ImageView-Zustand identisch zum initialen - * Zustand aus dem Konstruktor. Der {@link StackPane} zentriert den ImageView - * dann automatisch über die zuvor gesetzte {@code Pos.CENTER}-Ausrichtung; - * eine explizite H/V-Wert-Manipulation am ScrollPane ist im fit-Modus - * wirkungslos und daher nicht nötig. + *

Reihenfolge der Aktionen ist kritisch: + *

    + *
  1. {@code setFitToWidth(true)} und {@code setFitToHeight(true)} sofort, + * damit der nächste Layout-Pass den {@code viewStack} auf Viewport-Größe + * zurückrechnet.
  2. + *
  3. Property-Bindungen und H/V-Reset im {@code Platform.runLater}, damit + * sie auf die bereits zurückgerechneten {@code viewStack}-Dimensionen + * wirken und nicht auf die noch zoom-große Breite.
  4. + *
+ * Ohne diese Reihenfolge würden die Bindungen die imageView kurz an die + * Zoom-Größe koppeln, und ein verbleibender H/V-Wert aus dem Pan-/Zoom-Modus + * (z. B. {@code hvalue=0.0} nach Pan zum linken Rand) würde die PDF wegen + * kleinster Rounding-/Border-Differenzen links/oben bündig statt zentriert + * anzeigen, obwohl der ScrollPane fit-aktiv ist. */ private void resetToFitView() { zoomLevel = 1.0; @@ -760,10 +767,19 @@ public final class PdfPreviewPane { panStartY = -1; viewStack.setCursor(null); if (!scrollPane.isFitToWidth()) { - imageView.fitWidthProperty().bind(viewStack.widthProperty()); - imageView.fitHeightProperty().bind(viewStack.heightProperty()); + // 1. ScrollPane in Fit-Modus schalten, damit der nächste Layout-Pass + // den viewStack auf Viewport-Größe zurückrechnet scrollPane.setFitToWidth(true); scrollPane.setFitToHeight(true); + // 2./3. Bindings und H/V-Reset erst nach abgeschlossenem Layout-Pass, + // damit sie auf die zurückgerechneten Dimensionen wirken und + // Rounding-Reste aus Pan/Zoom die Zentrierung nicht verschieben + Platform.runLater(() -> { + imageView.fitWidthProperty().bind(viewStack.widthProperty()); + imageView.fitHeightProperty().bind(viewStack.heightProperty()); + scrollPane.setHvalue(0.5); + scrollPane.setVvalue(0.5); + }); } }