我有一些顶部装饰窗格,我想处理/预处理鼠标事件,但不应该使用它们,即所有重叠的窗格应该像装饰窗格不重叠一样工作。
怎么做?我多次尝试都失败了。
以下是包含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 :(得分:0)
您可以再次将greenPane
鼠标设置为透明,并将事件过滤器添加到root
以预处理鼠标事件:
greenPane.setMouseTransparent(true);
root.addEventFilter(MouseEvent.MOUSE_CLICKED, event -> System.out.println(event));
在事件处理的事件捕获阶段过滤接收事件,而在事件冒泡阶段触发处理程序。您也可以使用事件处理程序,但我认为在这种情况下过滤器更具惯用性(阅读更多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
仅用于预处理事件,则不再需要它。