0

I'm trying to add an overlay with a transparent background to my JavaFX application, this overlay should not change the way the mouse works or anything, it's just for cosmetic purpose.

I have something like this:

<StackPane>
    <VBox ... /> (The content)
    <Canvas /> (The overlay)
</StackPane>

But the problem here is that I cannot click on the VBox, because the Canvas is in front of it, so I tried to make the mouse transparent to the Canvas canvas.setMouseTransparent(true), but when I do this, everything works but all the Mouse Events don't fire anymore, for any of the elements: the canvas, the VBox, the StackPane, the Scene...

I also tried using setPickOnBounds(false) on the canvas, on the StackPane, but it doesn't work either (I can't click on the VBox node).

I feel like this is a JavaFX bug but I'm not sure, I would like to have your opinon.

EDIT
While doing some furthers testings, I've found the Mouse Moved Event is not called only when hovering an item from the content layer.

Here is an example code to reproduce the issue:

public class TestApp extends Application {

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

    @Override
    public void start(Stage primaryStage) {
        StackPane root = new StackPane();

        root.addEventHandler(MouseEvent.MOUSE_MOVED,
                event -> System.out.println(event.getX() + " / " + event.getY()));

        VBox content = new VBox();
        content.setBackground(new Background(new BackgroundFill(Color.CORNSILK, CornerRadii.EMPTY, Insets.EMPTY)));
        content.setFillWidth(true);

        Button test = new Button("This is a test button");
        test.setPrefWidth(500);
        test.setPrefHeight(100);

        content.getChildren().add(test);

        Canvas overlay = new Canvas();
        overlay.setWidth(1280);
        overlay.setHeight(720);
        overlay.setMouseTransparent(true);

        GraphicsContext context = overlay.getGraphicsContext2D();
        context.setFill(Color.color(1, 0.5, 0.5, 0.8));
        context.fillRect(0, 0, 1280, 720);

        root.getChildren().addAll(content, overlay);

        primaryStage.setScene(new Scene(root, 1280, 720));
        primaryStage.show();
    }
}

With this code, when I hover the button, I can see in the console that the MouseEvent is not called anymore, but when I hover nothing, the MouseEvent is called.

MinusKube
  • 67
  • 3
  • 8
  • Which one is the overlay? – Jai Jun 26 '18 at 02:43
  • Did you read the solution here: https://stackoverflow.com/questions/24607969/mouse-events-get-ignored-on-the-underlying-layer#24617790 ? It talks about `setPickOnBounds()` but offers more information surrounding it. – Zephyr Jun 26 '18 at 02:49
  • Possible duplicate of [Mouse Events get Ignored on the Underlying Layer](https://stackoverflow.com/questions/24607969/mouse-events-get-ignored-on-the-underlying-layer) – Zephyr Jun 26 '18 at 02:50
  • Cannot reproduce your issue... – fabian Jun 26 '18 at 09:20
  • @Jai The overlay is the Canvas – MinusKube Jun 26 '18 at 17:35
  • @fabian I just added a code to reproduce the issue :) – MinusKube Jun 26 '18 at 17:35
  • @Zephyr Yeah I read that, but setPickOnBounds doesn't change anything, I guess it's because I use a canvas maybe? – MinusKube Jun 26 '18 at 17:35
  • You know that event handlers are allowed to consume events to prevent the ancestors from receiving this event??? `Button` does this... – fabian Jun 26 '18 at 17:45
  • @fabian Mhhh... But how can I listen to the Mouse Move Event from my canvas or from my root, even when a button is hovered? – MinusKube Jun 26 '18 at 19:22
  • 1
    You need to use a event filter, not a event handler. Event filters are executed during the event capturing phase that happens before the event bubbling... – fabian Jun 26 '18 at 19:36
  • @fabian Okay, it works, thank you very much! – MinusKube Jun 26 '18 at 19:55

0 Answers0