From 15ff034a2b45b3ae7b11499378bcbe84a5469e95 Mon Sep 17 00:00:00 2001 From: Marcus van Elst Date: Tue, 5 May 2026 14:31:29 +0200 Subject: [PATCH] Behebe Zoom-Sprung und Zentrierung nach Rauszoomen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug 1: deltaY vor Akkumulation auf einen Notch-Wert begrenzen. Plattformspezifische Scroll-Multiplikatoren (Windows-Mausgeschwindigkeit, hohe DPI-Mäuse) können Werte wie 120 statt 40 liefern. Ohne Normierung akkumuliert sich ein Überlaufwert, der Folge-Events sofort auslöst. Bug 2: resetToFitView() setzt nach setFitToWidth(true) explizit scrollPane.setHvalue(0.5) und setVvalue(0.5) (nach layout()-Aufruf), damit vorherige Pan-Scroll-Werte die Zentrierung nicht nachwirken. Co-Authored-By: Claude Sonnet 4.6 --- .../in/gui/batchrun/PdfPreviewPane.java | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 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 cd47758..0ba219c 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 @@ -631,12 +631,19 @@ public final class PdfPreviewPane { * Pro Raste (ca. {@value #ZOOM_NOTCH_THRESHOLD} Einheiten) ändert sich der Zoom * um {@value #ZOOM_STEP}. Pro ScrollEvent wird maximal eine Zoom-Stufe angewendet. * + *

Der Rohwert von {@code deltaY} wird vor der Akkumulation auf einen + * Notch-Wert ({@value #ZOOM_NOTCH_THRESHOLD}) begrenzt. Plattformspezifische + * Scroll-Multiplikatoren (z. B. Windows-Mausgeschwindigkeit, hohe DPI-Mäuse) + * können sonst Werte wie 120 oder mehr pro Raste liefern, was einen + * Akkumulator-Überlauf in Folge-Events verursacht. + * * @param deltaY vertikaler Scroll-Delta des {@link ScrollEvent} */ private void accumulateAndApplyZoomDelta(double deltaY) { - zoomAccumulator += deltaY; - // 32a: Pro Mausrad-Raste genau eine Zoom-Stufe (if statt while verhindert - // mehrfaches Springen bei großen deltaY-Werten) + // Normierung: maximal einen Notch-Wert pro Event akkumulieren, um + // plattformspezifische deltaY-Überhöhungen (z. B. 120 statt 40) abzufangen + double capped = Math.signum(deltaY) * Math.min(Math.abs(deltaY), ZOOM_NOTCH_THRESHOLD); + zoomAccumulator += capped; if (zoomAccumulator >= ZOOM_NOTCH_THRESHOLD) { zoomAccumulator -= ZOOM_NOTCH_THRESHOLD; applyZoom(Math.min(ZOOM_MAX, zoomLevel + ZOOM_STEP)); @@ -700,12 +707,18 @@ 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. + * + *

Nach dem Reaktivieren von {@code fitToWidth} werden H- und V-Scroll-Werte + * explizit auf 0.5 gesetzt (nach einem {@code layout()}-Aufruf, damit die neuen + * Inhaltsgrenzen bekannt sind). Ohne diesen Schritt trägt der ScrollPane ggf. noch + * die H/V-Werte aus dem vorherigen Zoom-/Pan-Zustand und zeigt die PDF nach dem + * Reset nicht zentriert an. */ private void resetToFitView() { zoomLevel = 1.0; zoomAccumulator = 0.0; naturalViewportWidth = 0.0; - // 32e: Pan-Zustand und Mauszeiger zurücksetzen + // Pan-Zustand und Mauszeiger zurücksetzen panStartX = -1; panStartY = -1; viewStack.setCursor(null); @@ -714,6 +727,13 @@ public final class PdfPreviewPane { imageView.fitHeightProperty().bind(viewStack.heightProperty()); scrollPane.setFitToWidth(true); scrollPane.setFitToHeight(true); + // Zentrierung sicherstellen: nach layout() H/V auf Mitte setzen, + // damit verbleibende Scroll-Werte aus dem Zoom-/Pan-Modus nicht nachwirken + Platform.runLater(() -> { + scrollPane.layout(); + scrollPane.setHvalue(0.5); + scrollPane.setVvalue(0.5); + }); } }