画像ビューアーで、Ctrl を押しながらマウスホイールを回すと拡大縮小する機能を追加したいと思った。
ところが、マウスホイールを回すと ScrollPane もスクロールされてしまった。
結局、addEventFilter メソッドで指定するイベントハンドラにて、event.consume(); を実行していなかったからだった。
解決に思いの外時間を要したため記録しておく。
マウスホイールイベントを奪取する例は以下。
package application; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; import javafx.application.Application; import javafx.embed.swing.SwingFXUtils; import javafx.event.EventHandler; import javafx.stage.Stage; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.control.ScrollPane; import javafx.scene.image.ImageView; import javafx.scene.image.WritableImage; import javafx.scene.input.ScrollEvent; public class Main extends Application { boolean isMouseDragging = false; @Override public void start(Stage primaryStage) { try { BufferedImage bufferedImage = ImageIO.read(new File("test.png")); WritableImage writableImage = SwingFXUtils.toFXImage(bufferedImage, null); ImageView imageView = new ImageView(); imageView.setImage(writableImage); Group root = new Group(imageView); ScrollPane scrollPane = new ScrollPane(root); Scene scene = new Scene(scrollPane,400,400); scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm()); primaryStage.setScene(scene); primaryStage.show(); //マウス操作を検出 scene.setOnDragDetected(e -> System.out.println("setOnDragDetected")); scene.setOnDragDone(e -> System.out.println("setOnDragDone")); scene.setOnDragDropped(e -> System.out.println("setOnDragDropped")); scene.setOnDragEntered(e -> System.out.println("setOnDragEntered")); scene.setOnDragExited(e -> System.out.println("setOnDragExited")); scene.setOnDragOver(e -> System.out.println("setOnDragOver")); scene.setOnMouseClicked(e -> System.out.println("setOnMouseClicked")); scene.setOnMouseDragEntered(e -> System.out.println("setOnMouseDragEntered")); scene.setOnMouseDragExited(e -> System.out.println("setOnMouseDragExited")); scene.setOnMouseDragged(e -> System.out.println("setOnMouseDragged")); scene.setOnMouseDragOver(e -> System.out.println("setOnMouseDragOver")); scene.setOnMouseDragReleased(e -> System.out.println("setOnMouseDragReleased")); scene.setOnMouseMoved(e -> System.out.println("setOnMouseMoved")); scene.setOnMousePressed(e -> System.out.println("setOnMousePressed")); scene.setOnMouseReleased(e -> System.out.println("setOnMouseReleased")); scene.setOnScroll(e->System.out.println("setOnScroll")); imageView.addEventFilter(ScrollEvent.ANY, e -> {System.out.println("imageView.addEventFilter");}); scene.addEventFilter(ScrollEvent.ANY, e -> {System.out.println("scene.addEventFilter");}); primaryStage.addEventFilter(ScrollEvent.ANY, e -> {System.out.println("stage.addEventFilter");}); // ホイールでスクロールしないようにしたい scrollPane.addEventFilter(ScrollEvent.ANY, new EventHandler <ScrollEvent> () { @Override public void handle(ScrollEvent event) { System.out.println("override scrollPane.addEventFilter"); event.consume(); } }); scrollPane.setOnScroll(new EventHandler <ScrollEvent>() { @Override public void handle(ScrollEvent event) { System.out.println("scrollPane.setOnScroll"); } }); } catch(Exception e) { e.printStackTrace(); } } public static void main(String[] args) { launch(args); } }