2016-10-13 11 views
2

私は、マウスイベントを処理/前処理するいくつかの最上部のデコレーションペインを持っていますが、それらは消費してはいけません。つまり、デコレーションペインで重なっていないかのように、JavaFXの下にあるすべての重なったペインにマウスイベントを委譲するにはどうすればよいですか?

これを行う方法?私はいくつかの試みで失敗した。

以下は3つの枠付きコードです。緑色のものは「装飾」です。タスクは、マウスイベントに対して透過的にすることです。黄色と青のペインはワーカーペインです。あたかも緑の枠で覆われていないかのように働くべきです。

しかし、緑の枠はマウスイベントを受け取る必要があります。

import javafx.application.Application; 
import javafx.event.Event; 
import javafx.event.EventHandler; 
import javafx.event.EventType; 
import javafx.geometry.Insets; 
import javafx.scene.Scene; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.layout.*; 
import javafx.scene.paint.Color; 
import javafx.stage.Stage; 

/** 
* Created by dims on 13.10.2016. 
*/ 
public class DelegateEventsToOverlappedNodes extends Application{ 


    @Override 
    public void start(Stage primaryStage) throws Exception { 

     StackPane root = new StackPane(); 
     root.setBackground(new Background(new BackgroundFill(Color.RED, CornerRadii.EMPTY, Insets.EMPTY))); 


     AnchorPane yellowPane = new AnchorPane(); 
     yellowPane.setBackground(new Background(new BackgroundFill(Color.YELLOW, CornerRadii.EMPTY, Insets.EMPTY))); 
     yellowPane.setOnMouseClicked(new EventHandler<MouseEvent>() { 
     @Override 
     public void handle(MouseEvent event) { 
      System.out.println("yellowPane clicked"); 
     } 
     }); 


     root.getChildren().add(yellowPane); 


     Pane bluePane = new Pane(); 
     bluePane.setBackground(new Background(new BackgroundFill(Color.BLUE, CornerRadii.EMPTY, Insets.EMPTY))); 
     bluePane.setOnMouseClicked(new EventHandler<MouseEvent>() { 
     @Override 
     public void handle(MouseEvent event) { 
      System.out.println("bluePane clicked"); 
     } 
     }); 

     AnchorPane.setLeftAnchor(bluePane, 200.); 
     AnchorPane.setRightAnchor(bluePane, 200.); 
     AnchorPane.setTopAnchor(bluePane, 200.); 
     AnchorPane.setBottomAnchor(bluePane, 200.); 


     yellowPane.getChildren().add(bluePane); 




     AnchorPane greenPane = new AnchorPane(); 
     greenPane.setBackground(new Background(new BackgroundFill(Color.rgb(0, 255, 0, 0.9), CornerRadii.EMPTY, Insets.EMPTY))); 
     greenPane.setOnMouseClicked(new EventHandler<MouseEvent>() { 
     @Override 
     public void handle(MouseEvent event) { 
      System.out.println("greenPane clicked"); 
     } 
     }); 


     // greenPane.setVisible(false); // green pane invisible at all 

     // greenPane.setMouseTransparent(true); // green clicked doesn't occur 

     // greenPane.addEventHandler(Event.ANY, event -> yellowPane.fireEvent(event)); // works for yellow pane, but not for blue sub pane 



     root.getChildren().add(greenPane); 


     Scene scene = new Scene(root, 800, 600); 

     primaryStage.setScene(scene); 
     primaryStage.setTitle("DelegateEventsToOverlappedNodes"); 
     primaryStage.show(); 

    } 

    public static void main(String[] args) { 
     DelegateEventsToOverlappedNodes.launch(args); 
    } 
} 

答えて

0

あなたは再び透明greenPaneマウスを設定し、ここではマウスイベント前処理にrootにイベントフィルタを追加することができます::

greenPane.setMouseTransparent(true); 
root.addEventFilter(MouseEvent.MOUSE_CLICKED, event -> System.out.println(event)); 

はラインがI試みとコメントが間違って見えるもの言うことを示しているコメント

フィルタはイベント処理のイベント取得フェーズ中にイベントを受信しますが、ハンドラはイベントバブリングフェーズでトリガされます。また、イベントハンドラを使用することもできますが、フィルタはもっと慣れていると思います(詳細はhereを参照)。

あなたのコード:

import javafx.application.Application; 
import javafx.geometry.Insets; 
import javafx.scene.Scene; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.layout.*; 
import javafx.scene.paint.Color; 
import javafx.stage.Stage; 

public class DelegateEventsToOverlappedNodes extends Application { 

    public static void main(String[] args) { 
     DelegateEventsToOverlappedNodes.launch(args); 
    } 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     // Yellow pane. 
     AnchorPane yellowPane = new AnchorPane(); 
     yellowPane.setBackground(new Background(new BackgroundFill(Color.YELLOW, CornerRadii.EMPTY, Insets.EMPTY))); 
     yellowPane.setOnMouseClicked(event -> System.out.println("yellowPane clicked")); 

     // Blue pane. 
     AnchorPane bluePane = new AnchorPane(); 
     bluePane.setBackground(new Background(new BackgroundFill(Color.BLUE, CornerRadii.EMPTY, Insets.EMPTY))); 
     bluePane.setOnMouseClicked(event -> System.out.println("bluePane clicked")); 
     AnchorPane.setLeftAnchor(bluePane, 200.0); 
     AnchorPane.setRightAnchor(bluePane, 200.0); 
     AnchorPane.setTopAnchor(bluePane, 200.0); 
     AnchorPane.setBottomAnchor(bluePane, 200.0); 

     // Green pane. 
     AnchorPane greenPane = new AnchorPane(); 
     greenPane.setBackground(new Background(new BackgroundFill(Color.rgb(0, 255, 0, 0.9), CornerRadii.EMPTY, Insets.EMPTY))); 
     greenPane.setMouseTransparent(true); 

     // Root pane. 
     StackPane rootPane = new StackPane(); 
     rootPane.setBackground(new Background(new BackgroundFill(Color.RED, CornerRadii.EMPTY, Insets.EMPTY))); 
     rootPane.addEventFilter(MouseEvent.MOUSE_CLICKED, event -> System.out.println(event)); 

     // Layout and scene. 
     yellowPane.getChildren().add(bluePane); 
     rootPane.getChildren().addAll(yellowPane, greenPane); 

     primaryStage.setScene(new Scene(rootPane, 800.0, 600.0)); 
     primaryStage.setTitle("DelegateEventsToOverlappedNodes"); 
     primaryStage.show(); 
    } 

} 

あなただけの前処理イベントにgreenPaneを作成した場合は、もうそれは必要ありません。

関連する問題