Fange JavaFX-Reset von hvalue mit ChangeListener ab statt per Timing
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 <noreply@anthropic.com>
This commit is contained in:
+16
-10
@@ -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<Number>[] 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();
|
||||
|
||||
Reference in New Issue
Block a user