とにかく書く

日々の雑感や知り得たことを、とにかく書いています

イベントを捕捉して処理する

画像ビューアーで、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);
	}
}