JavaFX单击以覆盖堆栈窗格 [英] JavaFX Click through overlaying stackpane

查看:144
本文介绍了JavaFX单击以覆盖堆栈窗格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如您在上图中所见,我有一个包含两个元素的堆栈窗格,一个BorderPane(它又包含一个画布和一个状态栏)和另一个堆栈窗格(其中包含一些其他UI东西).

我希望能够从绿色堆栈窗格的不可见区域单击到黄色边框窗格,但仍然可以单击绿色堆栈窗格上的实际UI内容(其中有可单击的东西,例如按钮等).

您如何做到的?

解决方案

您可以使用stackPane.setPickOnBounds(false);.这意味着,仅当单击堆栈窗格的点不是透明的时,才会将堆栈窗格标识为鼠标动作的目标(而不是默认行为,默认行为是,如果鼠标单击鼠标,则将其标识为鼠标动作的目标)点击是在其范围之内).

这是SSCCE:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class ClickThroughStackPane extends Application {

    @Override
    public void start(Stage primaryStage) {
        Canvas canvas = new Canvas(400,400);
        canvas.setOnMouseClicked(e -> System.out.println("Mouse click: canvas"));
        HBox statusBar = new HBox(new Label("Status"));
        statusBar.setOnMouseClicked(e -> System.out.println("Mouse click: statusBar"));
        BorderPane borderPane = new BorderPane(canvas, statusBar, null, null, null);

        Button button = new Button("Click");
        button.setOnAction(e -> System.out.println("Button pressed"));
        StackPane stack = new StackPane(button);

        stack.setPickOnBounds(false);

        StackPane root = new StackPane(borderPane, stack);
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }

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

请注意,顶部堆栈窗格似乎不必要,因为您可以直接将其包含的UI元素直接添加到基础堆栈窗格中.前面的示例可以简单地重写:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class ClickThroughStackPane extends Application {

    @Override
    public void start(Stage primaryStage) {
        Canvas canvas = new Canvas(400,400);
        canvas.setOnMouseClicked(e -> System.out.println("Mouse click: canvas"));
        HBox statusBar = new HBox(new Label("Status"));
        statusBar.setOnMouseClicked(e -> System.out.println("Mouse click: statusBar"));
        BorderPane borderPane = new BorderPane(canvas, statusBar, null, null, null);

        Button button = new Button("Click");
        button.setOnAction(e -> System.out.println("Button pressed"));

        StackPane root = new StackPane(borderPane, button);
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }

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

As you can see in the drawing above, I have a stackpane containing two elements, a BorderPane (which again contains a canvas and a statusbar) and another stackpane (which contains some other UI things).

I'd like to be able to click through from invisible areas of the green stackpane to the yellow borderpane but still allow clicking on actual UI stuff on the green stackpane (where there is clickable things like buttons etc.).

How do you do this?

解决方案

You can use stackPane.setPickOnBounds(false);. This means that the stack pane will only be identified as the target of a mouse action if the point on which it was clicked was not transparent (instead of the default behavior, which is to identify it as the target of the mouse action if the mouse click is within its bounds).

Here is an SSCCE:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class ClickThroughStackPane extends Application {

    @Override
    public void start(Stage primaryStage) {
        Canvas canvas = new Canvas(400,400);
        canvas.setOnMouseClicked(e -> System.out.println("Mouse click: canvas"));
        HBox statusBar = new HBox(new Label("Status"));
        statusBar.setOnMouseClicked(e -> System.out.println("Mouse click: statusBar"));
        BorderPane borderPane = new BorderPane(canvas, statusBar, null, null, null);

        Button button = new Button("Click");
        button.setOnAction(e -> System.out.println("Button pressed"));
        StackPane stack = new StackPane(button);

        stack.setPickOnBounds(false);

        StackPane root = new StackPane(borderPane, stack);
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }

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

Note that the top stack pane seems unnecessary, as you could simply add the UI elements it contains directly to the underlying stack pane. The previous example could simply be rewritten:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class ClickThroughStackPane extends Application {

    @Override
    public void start(Stage primaryStage) {
        Canvas canvas = new Canvas(400,400);
        canvas.setOnMouseClicked(e -> System.out.println("Mouse click: canvas"));
        HBox statusBar = new HBox(new Label("Status"));
        statusBar.setOnMouseClicked(e -> System.out.println("Mouse click: statusBar"));
        BorderPane borderPane = new BorderPane(canvas, statusBar, null, null, null);

        Button button = new Button("Click");
        button.setOnAction(e -> System.out.println("Button pressed"));

        StackPane root = new StackPane(borderPane, button);
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }

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

这篇关于JavaFX单击以覆盖堆栈窗格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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