Search code examples
javajavafxmouseeventsplitpane

JavaFX SplitPane does not bubble up mouse event


I have a BorderPane. In this pane I have set as the top an HBox with several controls. In the center I have e SplitPane that has two canvases. I want to get a mouse move at the BorderPane when it bubbles up from the SplitPane.

If I use a splitPane.setOnMouseMoved(...) I get the event correctly. However a BorderPane.setOnMouseMoved(...) only works when the mouse hovers over the top (were the HBox is found).

It seems like the SplitPane is consuming the event. Can anyone confirm this? If so how do I get the even to bubble up? Note that when I apply a filter the even is detected at the BorderPane level on the way down.

TIA


Solution

  • Most, if not all, skin implementations extend from SkinBase which consumes all mouse events by default. You can configure this via the protected consumeMouseEvents(boolean) method. As the method is protected you'll have to subclass the skin (or use reflection) to access it:

    package com.example;
    
    import javafx.scene.control.SplitPane;
    import javafx.scene.control.skin.SplitPaneSkin;
    
    public class MySplitPaneSkin extends SplitPaneSkin {
    
        public MySplitPaneSkin(SplitPane control) {
            super(control);
            consumeMouseEvents(false);
        }
    
    }
    

    The skin classes became public API in JavaFX 9. If you're using JavaFX 8 you'll need to extend the internal skin class.

    You would then set the skin of the SplitPane.

    SplitPane pane = ...;
    pane.setSkin(new MySplitPaneSkin(pane));
    

    You can also set the skin using CSS via the -fx-skin property:

    .split-pane {
        -fx-skin: com.example.MySplitPaneSkin;
    }
    

    Note that using CSS as above will set the skin for all SplitPanes covered by the stylesheet (unless you change their styleclass). You may wish to make this more specific by giving your SplitPane an ID and using #id { ... }.

    Also, looking at the SplitPaneSkin implementation in JavaFX 11.0.2, an event handler is added to each divider which consumes all events. As this is a private implementation detail you can't change this behavior. In other words, even with the above code, mouse events won't bubble up to your BorderPane when the mouse is over a divider.

    Another thing to consider is that any controls in the SplitPane will likely also consume mouse events. You'd need to apply something similar to the above for each such child control.