【问题标题】:JavaFX: Node under node event handlingJavaFX:节点事件处理下的节点
【发布时间】:2015-12-20 08:15:16
【问题描述】:

我正在做一个项目,我在 StackPane 中有一个 GUI(BorderPane) 和一个可移动地图(Pane),但是当我想点击地图或他的一个孩子时,事件处理程序仅在 GUI 上处理.我该如何解决这个问题?

我将所有对象放在地图窗格中,然后将此窗格移动到另一个窗格中。

这里有一些代码:

Pane Map = new Pane();
Map.getChildren().addAll(...);
Map.setLayoutX(0);
Map.setLayoutY(0);
Map.setOnMouseClicked(e-> System.out.println("Click1"));

GUI = new BorderPane();
GUI.getChildren().addAll(...);
GUI.setOnMouseClicked(e -> System.out.println("Click2"));

MovableMap = new Pane();
MovableMap.getChildren().add(Map);
MovableMap.setOnMouseClicked(e -> System.out.println("Click3"));

StackPane root = new StackPane();
root.getChildren().addAll(MovableMap,GUI);
root.setOnMouseClicked(e -> System.out.println("Click4"));

【问题讨论】:

标签: java javafx


【解决方案1】:

前段时间我遇到了完全相同的问题。当您以某种方式将它们放在彼此之上时,所有窗格(不仅是 StackPane)似乎都会吞噬所有事件。我只能通过手动布局 GUI 窗格来解决这个问题。从概念上讲,我做了这样的事情:

    private BorderPane root;
    private MapPane mapPane;
    private GUIPane guiPane;

    @Override
    public void start(Stage stage) {
        root = new BorderPane();
        mapPane = new MapPane();            
        guiPane = new GUIPane();

        guiPane.setManaged(false);

        root.setCenter(mapPane);
        root.getChildren().add(guiPane);

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

        stage.setScene(scene);
        stage.show();

        guiPane.autosize();
        guiPane.layoutXProperty().bind(root.widthProperty().subtract(guiPane.widthProperty()).divide(2));
        guiPane.setLayoutY(20);
    }

它对我有用,但我很想听听一个更好的解决方案。

【讨论】:

    【解决方案2】:

    您可以使任何窗格“鼠标透明”,这样它就不会消耗 任何点击事件,并让它们传递到它下面的堆栈。

    这是一些示例代码...这个示例在堆栈中设置了 4 个窗格, 开始时只有 mainPane 接受点击。

    StackPane rootPane = new StackPane();
    VBox mainPane = new VBox(80);
    
    BorderPane helpOverlayPane = new BorderPane();
    helpOverlayPane.setMouseTransparent(true);
    
    Canvas fullScreenOverlayCanvas = new Canvas();
    fullScreenOverlayCanvas.setMouseTransparent(true);
    
    VBox debugPane = new VBox();
    debugPane.setAlignment(Pos.BASELINE_RIGHT);
    AnchorPane debugOverlay = new AnchorPane();
    debugOverlay.setMouseTransparent(true);
    debugOverlay.getChildren().add(debugPane);
    AnchorPane.setBottomAnchor(debugPane, 80.0);
    AnchorPane.setRightAnchor(debugPane, 20.0);
    
    rootPane.getChildren().addAll(mainPane, fullScreenOverlayCanvas, debugOverlay, helpOverlayPane);
    

    现在,当您想使用画布在顶部绘图时,请确保您 仅针对该堆栈将鼠标透明更改为 false,并保留所有 它上面的窗格鼠标透明。

    fullScreenOverlayCanvas.setMouseTransparent(false);
    debugOverlay.setMouseTransparent(true);
    fullScreenOverlayCanvas.setVisible(true);
    
    doSomethingWithCanvasThatNeedsMouseClicks();
    

    附:我对我拥有的代码进行了一些编辑,因此它可能无法按原样运行。 另外,请参阅此处仅使部分窗格透明的讨论: JavaFX Pass MouseEvents through Transparent Node to Children

    https://stackoverflow.com/a/21062186/4464702

    【讨论】:

    • 我不知道原作者的意图,但切换窗格的鼠标透明度对我来说是没有选择的。这更像是您在上一个链接中提到的问题(JavaFX Pass MouseEvents ...),但我从来没有让那个例子工作,而且代码对我来说也很可疑。我只是看不出这个 pickOnBounds 属性在这种情况下应该有什么积极影响。
    猜你喜欢
    • 1970-01-01
    • 2014-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-18
    • 1970-01-01
    • 1970-01-01
    • 2013-05-28
    相关资源
    最近更新 更多