我有两层(= AnchorPanes)与StackPane堆叠在一起。所以这两个层都填满整个场景。问题是,只有顶层才会收到鼠标事件。
这是如何构建场景的:
只有按钮B接收点击事件,但按钮A没有。
如果我将图层B设置为鼠标透明(layerB.setMouseTransparent(true)
),则按钮A会接收鼠标事件。但鼠标透明效果也是所有孩子,因此Button B不再接收鼠标事件。
如何让按钮A和按钮B接收鼠标事件?
以下是完整的工作来源:
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);
}
}
答案 0 :(得分:33)
解决方案
将以下行添加到示例代码中:
layerB.setPickOnBounds(false);
这将允许鼠标与您可以通过堆叠元素的图层看到的可见元素进行交互。
如果顶层中的元素与底层中的元素重叠,则单击顶层的与底层重叠的部分将使顶层消耗鼠标事件而底层将不会接收它(这可能是什么你要)。
替代性解释
如果你真的想拦截并处理所有图层中的鼠标事件,那么请查看Uluk评论中的链接问题:
方法说明
setPickOnBounds方法的说明:
定义在由
MouseEvent
或包含函数调用触发时如何为此节点执行拾取计算。如果pickOnBounds
为真,则通过与此节点的边界相交来计算拾取,否则通过与此节点的几何形状相交来计算拾取。
默认情况下,窗格没有可见的背景,那么他们为什么要使用鼠标事件呢?
对于modena.css,JavaFX 8附带的默认样式表,Panes默认情况下实际上具有非常微弱的阴影背景,因此它们可以使用鼠标事件。要防止这种情况,您可以将窗格的背景颜色设置为null,或将窗格设置为mouseTransparent。
这种行为在JavaFX 2和JavaFX 8之间发生了变化.JavaFX 2附带了一个名为caspian.css的默认样式表,它没有为Panes设置背景。
答案 1 :(得分:1)
由于事件被LayerB捕获,因此无法工作。 您可以将LayerB设置为MouseTransparent
layerB.setMouseTransparent(true)
但我不确定按钮b是否也是鼠标后的。
试试吧,你对不同的布局有所了解吗?