如何在JavaFX中将鼠标事件委托给所有底层重叠窗格?

如何在JavaFX中将鼠标事件委托给所有底层重叠窗格?,java,javafx,mouseevent,glasspane,Java,Javafx,Mouseevent,Glasspane,我有一些顶部装饰窗格,我想处理/预处理鼠标事件,但不应该使用它们,即所有重叠的窗格都应该像装饰窗格没有重叠一样工作 如何做到这一点?我几次尝试都失败了 下面是一个带有3个窗格的代码。绿色的是“装饰”。任务是使其对鼠标事件透明。黄色和蓝色窗格是工作窗格。它们应该像没有被绿色窗格重叠一样工作 但绿色窗格仍应接收鼠标事件 注释行表示我尝试的内容,注释表示出现错误的内容: import javafx.application.Application; import javafx.event.Event;

我有一些顶部装饰窗格,我想处理/预处理鼠标事件,但不应该使用它们,即所有重叠的窗格都应该像装饰窗格没有重叠一样工作

如何做到这一点?我几次尝试都失败了

下面是一个带有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);
   }
}
导入javafx.application.application;
导入javafx.event.event;
导入javafx.event.EventHandler;
导入javafx.event.EventType;
导入javafx.geometry.Insets;
导入javafx.scene.scene;
导入javafx.scene.input.MouseEvent;
导入javafx.scene.layout.*;
导入javafx.scene.paint.Color;
导入javafx.stage.stage;
/**
*由dims于2016年10月13日创建。
*/
公共类DelegateEventsToOverlappedNodes扩展应用程序{
@凌驾
public void start(Stage primaryStage)引发异常{
StackPane root=新的StackPane();
根.立根背景(新背景(新背景填充(Color.RED,CornerRadii.EMPTY,Insets.EMPTY));
锚烷黄色窗格=新锚烷();
黄色窗格。背景(新背景(新背景填充(Color.YELLOW,CornerRadii.EMPTY,Insets.EMPTY));
setOnMouseClicked(新的EventHandler(){
@凌驾
公共无效句柄(MouseeEvent事件){
System.out.println(“单击黄色窗格”);
}
});
root.getChildren().add(黄色窗格);
窗格bluePane=新窗格();
bluePane.setBackground(新背景(新背景填充(Color.BLUE,CornerRadii.EMPTY,Insets.EMPTY));
setOnMouseClicked(新的EventHandler(){
@凌驾
公共无效句柄(MouseeEvent事件){
System.out.println(“单击蓝色窗格”);
}
});
AnchorPane.setLeftAnchor(蓝色窗格,200);
AnchorPane.setRightAnchor(蓝色窗格,200);
AnchorPane.setTopAnchor(蓝色窗格玻璃,200);
锚烷立根摇床(蓝色窗格玻璃,200);
yellowPane.getChildren().add(bluePane);
锚烷绿窗格=新锚烷();
绿色窗格。收进背景(新背景(新背景填充(Color.rgb(0,255,0,0.9),CornerRadii.EMPTY,Insets.EMPTY));
setOnMouseClicked(新的EventHandler(){
@凌驾
公共无效句柄(MouseeEvent事件){
System.out.println(“绿色窗格单击”);
}
});
//greenPane.setVisible(false);//绿色窗格根本不可见
//greenPane.setMouseTransparent(true);//绿色单击不会发生
//greenPane.addEventHandler(Event.ANY,Event->yellowPane.fireEvent(Event));//适用于黄色窗格,但不适用于蓝色子窗格
root.getChildren().add(绿色窗格);
场景=新场景(根,800600);
初级阶段。场景(场景);
setTitle(“DelegateEventsToOverlappedNodes”);
primaryStage.show();
}
公共静态void main(字符串[]args){
DelegateEventsToOverlappedNodes.launch(args);
}
}

您可以再次将
绿色窗格
鼠标设置为透明,并将事件过滤器添加到
根目录
中,以在此处预处理鼠标事件:

greenPane.setMouseTransparent(true);
root.addEventFilter(MouseEvent.MOUSE_单击,事件->系统.out.println(事件));
过滤器在事件处理的事件捕获阶段接收事件,而处理程序在事件冒泡阶段触发。您也可以使用事件处理程序,但我认为过滤器在本例中更为惯用(请参阅更多)

您的代码:

导入javafx.application.application;
导入javafx.geometry.Insets;
导入javafx.scene.scene;
导入javafx.scene.input.MouseEvent;
导入javafx.scene.layout.*;
导入javafx.scene.paint.Color;
导入javafx.stage.stage;
公共类DelegateEventsToOverlappedNodes扩展应用程序{
公共静态void main(字符串[]args){
DelegateEventsToOverlappedNodes.launch(args);
}
@凌驾
public void start(Stage primaryStage)引发异常{
//黄色窗格。
锚烷黄色窗格=新锚烷();
黄色窗格。背景(新背景(新背景填充(Color.YELLOW,CornerRadii.EMPTY,Insets.EMPTY));
yellowPane.setOnMouseClicked(事件->系统.out.println(“yellowPane已点击”);
//蓝色窗格。
锚烷蓝窗格玻璃=新锚烷();
bluePane.setBackground(新背景(新背景填充(Color.BLUE,CornerRadii.EMPTY,Insets.EMPTY));
bluePane.setOnMouseClicked(事件->系统.out.println(“bluePane已点击”);
AnchorPane.setLeftAnchor(蓝色窗格玻璃,200.0);
AnchorPane.setRightAnchor(蓝色窗格玻璃,200.0);
AnchorPane.setTopAnchor(蓝色窗格玻璃,200.0);
锚烷立根摇床(蓝色窗格玻璃,200.0);
//绿色窗格。
锚烷绿窗格=新锚烷();
绿色窗格。收进背景(新背景(新背景填充(Color.rgb(0,255,0,0.9),CornerRadii.EMPTY,Insets.EMPTY));
greenPane.setMouseTransparent(true);
//根窗格。
StackPane rootPane=新的StackPane();
根窗格.setBackground(新背景(新背景填充(Color.RED,CornerRadii.EMPTY,Insets.EMPTY));
addEventFilter(MouseEvent.MOUSE_单击,事件->系统.out.println(事件));
//布局和场景。
yellowPane.getChildren().add(bluePane);
rootPane.getChildren().addAll(黄色窗格,绿色窗格);
设置场景(新场景(根窗格,800.0600.0));
setTitle(“DelegateEventsToOverlappedNodes”);
primaryStage.show();
}
}
如果您仅为预处理创建了绿色窗格