鼠标事件在底层被忽略 [英] Mouse Events get Ignored on the Underlying Layer

查看:28
本文介绍了鼠标事件在底层被忽略的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两层(= AnchorPanes),其中一层与 StackPane 堆叠在一起.所以这两个层都填满了整个场景.问题是,只有顶层接收鼠标事件.

场景就是这样构建的:

只有按钮 B 接收点击事件,而按钮 A 没有.

如果我将图层 B 设置为鼠标透明 (layerB.setMouseTransparent(true)),按钮 A 将接收鼠标事件.但是鼠标透明也会影响所有孩子,所以按钮 B 不再接收鼠标事件.

如何让Button A和Button B接收鼠标事件?

这里是完整的工作源:

public class LayerTest extends Application {@覆盖public void start(final Stage primaryStage) 抛出异常 {最终节点 layerA = createLayerA();最终节点 layerB = createLayerB();最终的父根 = 新的 StackPane(layerA, layerB);最终场景场景 = 新场景(根);primaryStage.setScene(场景);primaryStage.setWidth(250);primaryStage.setHeight(200);primaryStage.show();}私有节点 createLayerA() {最后的 AnchorPane layerA = new AnchorPane();final Button buttonA = new Button("Button A");AnchorPane.setLeftAnchor(buttonA, 10d);AnchorPane.setTopAnchor(buttonA, 10d);buttonA.setOnMouseClicked(e -> System.out.println("Button A clicked"));layerA.getChildren().setAll(buttonA);返回层A;}私有节点 createLayerB() {最后的 AnchorPane layerB = new AnchorPane();final Button buttonB = new Button("Button B");AnchorPane.setRightAnchor(buttonB, 10d);AnchorPane.setBottomAnchor(buttonB, 10d);buttonB.setOnMouseClicked(e -> System.out.println("Button B被点击"));layerB.getChildren().setAll(buttonB);返回层B;}公共静态无效主(字符串 [] args){发射(参数);}}

解决方案

解决方案

将以下行添加到您的示例代码中:

layerB.setPickOnBounds(false);

这将允许鼠标与您可以通过堆叠元素的层看到的可见元素进行交互.

如果顶层元素与底层元素重叠,点击顶层与底层重叠的部分,顶层会消耗鼠标事件,底层不会接收到它(这可能是你要).

替代解释

如果您真的想拦截和处理所有层中的鼠标事件,请查看 Uluk 评论中的链接问题:

方法说明

setPickOnBounds<的描述/a> 方法:

<块引用>

定义当由 MouseEvent 或 contains 函数调用触发时,如何为此节点完成拾取计算.如果 pickOnBounds 为真,则通过与此节点的边界相交来计算拾取,否则通过与此节点的几何形状相交来计算拾取.

<小时><块引用>

窗格默认没有可见的背景,那么为什么它们要消耗鼠标事件呢?

对于 modena.css,JavaFX 8 附带的默认样式表,窗格实际上默认具有非常微弱的阴影背景,因此它们可以使用鼠标事件.为了防止这种情况,您可以将窗格的背景颜色设置为 null 或将窗格设置为 mouseTransparent.

此行为在 JavaFX 2 和 JavaFX 8 之间发生了变化.JavaFX 2 附带一个名为 caspian.css 的默认样式表,它不会为窗格设置背景.

I have two layers (= AnchorPanes) stacked one of the other with a StackPane. So both layer fill the whole scene. The problem is, that only the top layer receives mouse events.

Thats how the scene is build:

Only Button B receives click events but Button A not.

If I set Layer B to mouse transparent (layerB.setMouseTransparent(true)), Button A receives mouse events. But mouse transparent effects also all children, so Button B dont receives mouse events any more.

How to get Button A and Button B to receive mouse events?

Here is the full working source:

public class LayerTest extends Application {
    @Override
    public void start(final Stage primaryStage) throws Exception {
        final Node layerA = createLayerA();
        final Node layerB = createLayerB();
        final Parent root = new StackPane(layerA, layerB);
        final Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.setWidth(250);
        primaryStage.setHeight(200);
        primaryStage.show();
    }

    private Node createLayerA() {
        final AnchorPane layerA = new AnchorPane();
        final Button buttonA = new Button("Button A");
        AnchorPane.setLeftAnchor(buttonA, 10d);
        AnchorPane.setTopAnchor(buttonA, 10d);
        buttonA.setOnMouseClicked(e -> System.out.println("Button A clicked"));
        layerA.getChildren().setAll(buttonA);
        return layerA;
    }

    private Node createLayerB() {
        final AnchorPane layerB = new AnchorPane();
        final Button buttonB = new Button("Button B");
        AnchorPane.setRightAnchor(buttonB, 10d);
        AnchorPane.setBottomAnchor(buttonB, 10d);
        buttonB.setOnMouseClicked(e -> System.out.println("Button B clicked"));
        layerB.getChildren().setAll(buttonB);
        return layerB;
    }

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

解决方案

Solution

Add the following line to your sample code:

layerB.setPickOnBounds(false);

This will allow the mouse to interact with the visible elements you can see through the layers of your stacked elements.

If elements in the top layer overlap elements in the bottom layer clicking on the part of the top layer which overlaps the bottom layer will have the top layer consume the mouse event and the bottom layer will not receive it (which is probably what you want).

Alternate Interpretation

If you actually wanted to intercept and handle the mouse event in all layers then see the linked questions from Uluk's comments:

Method Description

A description of the setPickOnBounds method:

Defines how the picking computation is done for this node when triggered by a MouseEvent or a contains function call. If pickOnBounds is true, then picking is computed by intersecting with the bounds of this node, else picking is computed by intersecting with the geometric shape of this node.


Panes have no visible background by default, so why they should consume mouse events?

For modena.css, the default stylesheet that ships with JavaFX 8, Panes actually do have a very faint shaded background by default, so they can consume mouse events. To prevent this you can either set the background color of the pane to null or set the Pane to mouseTransparent.

This behavior changed between JavaFX 2 and JavaFX 8. JavaFX 2 shipped with a default stylesheet named caspian.css, which does not set a background for Panes.

这篇关于鼠标事件在底层被忽略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆