javajavafxinteractionpane

How do i prevent pane intersection blocking another pane? javafx


So as in the example code i have two panes (for now A and B) where A pane is above B my problem is that if A pane's bounds are intersecting with B pane's bounds A pane is blocking B pane preventing me to interact with it's children i hope my example code can explain it better what i want.

So what i want to achive is to be able to interact with Rectangle globalPaneR with the current bounds of the panes.

package stackoverflow;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class StcakOverFlow extends Application
{
    public static final Pane uiPane = new Pane();
    public static final Pane global_pane = new Pane();
    private Pane localPane = new Pane(global_pane, uiPane);

    @Override
    public void init()
    {
        Rectangle leftTopR = new Rectangle(25, 25, 50, 50);
        Rectangle rightBottomR = new Rectangle(700, 700, 50, 50);
        Rectangle globalPaneR = new Rectangle(600, 600, 50, 50);
        leftTopR.setFill(Color.RED);
        rightBottomR.setFill(Color.YELLOW);
        globalPaneR.setFill(Color.BLUE);

        globalPaneR.setOnMouseClicked(e -> globalPaneR.setFill(Color.LIME));

        uiPane.getChildren().addAll(leftTopR, rightBottomR);
        global_pane.getChildren().add(globalPaneR);
    }

    @Override
    public void start(Stage stage)
    {
        Scene scene = new Scene(localPane);
        stage.setScene(scene);
        stage.setTitle("StackOverFlow");
        stage.show();
    }

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

Solution

  • As you've already noticed the uiPane is placed on top of the global_pane and therefore consuming the all mouse events that should reach the globalPaneR rectangle. In this example this can be overcome in several ways:

    Option 1 (most universal): Set pickOnBounds property value of your 'blocking' pane to false.

    uiPane.setPickOnBounds(false);
    

    Documentation says about the pickOnBoundsProperty:

    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. The default value of this property is false unless overridden by a subclass. The default value is true for Region.

    So in this case this basically means that the uiPane should not consume mouse events unless the mouse is hovering over it's children (rectangles).

    Option 2: Use Group instead of Pane for your nodes which contain the rectangles.

    public static final Group uiPane = new Group();
    

    This works because Group doesn't inherit from Region (as Pane does) and therefore pickOnBounds property already has the default value false.

    Option 3: Change the order of your panes.

    Obviously this isn't always possible as you may want to listen to mouse events in both panes and may want the children of uiPane stay on top of global_pane. But in this simple example it would work to just reorder them like this:

    private Pane localPane = new Pane(uiPane, global_pane);