Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFX Click through overlaying stackpane

schematic

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?

like image 482
Petter Thowsen Avatar asked Nov 18 '16 13:11

Petter Thowsen


People also ask

How do I use stack pane in JavaFX?

JavaFX StackPane The StackPane layout pane places all the nodes into a single stack where every new node gets placed on the top of the previous node. It is represented by javafx.scene.layout.StackPane class. We just need to instantiate this class to implement StackPane layout into our application.

How to align nodes within the stackpane in JavaFX?

The node added first is placed at the bottom of the stack and the next node is placed on top of it. The class named StackPane of the package javafx.scene.layout represents the StackPane. This class contains a single property named alignment. This property represents the alignment of the nodes within the stack pane.

What is stackpane layout pane in Java?

The StackPane layout pane places all the nodes into a single stack where every new node gets placed on the top of the previous node. It is represented by javafx.scene.layout.StackPane class.

How do I put a component in the front of stackpane?

You can put a certain subcomponent in front of Stack via method named toFront (), or put the subcomponent in the bottom of Stack via method named toBack () . Normally, you only display the subcomponent on the top of StackPane and hide other subcomponents.


1 Answers

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);
    }
}
like image 139
James_D Avatar answered Oct 22 '22 10:10

James_D