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); + }); } }