Issue
I have a JavaFX application with a ScrollPane that handles resizing of nodes upon scrollEvents. However when the JavaFX stage (or Window) is not focused, I get an odd behaviour that I think might be a JFX bug, though wondering if anyone has encountered or managed to resolve it.
To replicate the issue, if you lose focus on the JavaFX window and perform some scrolling using the mouse-wheel on another window (eg your browser), and then relatively quickly move your mouse back to re-enter the JavaFX window (without clicking, scrolling or focusing upon the JavaFX window) the JavaFX window receives a bunch of scrollEvents despite no mouse-wheel action being performed.
I'm wondering if anyone has encountered this and worked out a way to somehow filter these odd scrollEvents out as it results in some strange zooming action that is unexpected given the lack of mouse-wheel scrolling!
I'm using Java & JavaFX 17 (OpenJFX), see below sample application that demonstrates, thanks!
public class ScrollEventIssueApplication extends Application {
@Override
public void start(Stage primaryStage) {
BorderPane borderPane = new BorderPane ();
borderPane .setPrefWidth(600);
borderPane .setPrefHeight(600);
Pane content = new Pane();
content.setPrefWidth(1000);
content.setPrefHeight(1800);
ScrollPane scrollPane = new ScrollPane(content);
scrollPane.setPrefWidth(700);
scrollPane.setPrefHeight(700);
content.setOnScroll(event -> {
System.out.println("Scroll event received: " + event.getDeltaY());
});
borderPane.setCenter(scrollPane);
Scene scene = new Scene(borderPane, 1800, 900);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Solution
It appears that this may be a platform-dependent feature of the installed pointing device and driver. I could occasionally reproduce the effect on Mac OS X 12 with JavaFX 17, but only when I also accidentally raked an errant finger or two across the mouse's multi-touch surface.
For reference, I tested the following simpler variation. Note code to enumerate the OS and Java version numbers, as well as changes to the viewport dimensions in order to show the scroll bars when set to AS_NEEDED
by default.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
/** @see https://stackoverflow.com/q/72485336/230513 */
public class ScrollTest extends Application {
private static final double W = 640;
private static final double H = 480;
@Override
public void start(Stage stage) {
Pane content = new StackPane();
content.getChildren().addAll(new Rectangle(W, H, Color.BLUE),
new Circle(Math.min(W, H) / 2, Color.LIGHTBLUE));
ScrollPane scrollPane = new ScrollPane(content);
scrollPane.setPrefViewportWidth(2 * W / 3);
scrollPane.setPrefViewportHeight(2 * H / 3);
content.setOnScroll(event -> System.out.println(
"dx dy: " + event.getDeltaX() + " " + event.getDeltaY()));
stage.setScene(new Scene(scrollPane));
stage.show();
}
public static void main(String[] args) {
System.out.println(System.getProperty("os.name")
+ " v" + System.getProperty("os.version")
+ "; Java v" + System.getProperty("java.version")
+ "; JavaFX v" + System.getProperty("javafx.runtime.version"));
launch(args);
}
}
Answered By - trashgod
Answer Checked By - Clifford M. (JavaFixing Volunteer)