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