gpt4 book ai didi

java - 如何将鼠标事件委托(delegate)给 JavaFX 中的所有底层重叠 Pane ?

转载 作者:行者123 更新时间:2023-12-05 07:47:15 25 4
gpt4 key购买 nike

我有一些顶部装饰面板,我想处理/预处理鼠标事件,但不应该消耗它们,即所有重叠的面板应该像没有被装饰面板重叠一样工作。

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

下面是一个包含 3 个 Pane 的代码。绿色的是“装饰”。任务是使其对鼠标事件透明。黄色和蓝色 Pane 是工作 Pane 。它们应该像没有被绿色 Pane 重叠一样工作。

但是绿色 Pane 仍然应该接收鼠标事件。

注释行表示我的尝试,注释表示出现的错误:

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);
}
}

最佳答案

您可以再次设置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 只是为了预处理事件,则不再需要它。

关于java - 如何将鼠标事件委托(delegate)给 JavaFX 中的所有底层重叠 Pane ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40023260/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com