Michael
Michael

Reputation: 127

How to add listener to divider position?

Is there a way to add listener whenever I resize my splitpane?
I currently have

split.getDividers().get(0).positionProperty().addListener(new ChangeListener<Number>(){
    public void changed(ObservableValue<? extends Number> observableValue, Number oldWindowWidth, Number newWindowWidth){
        //code
    }
});

which detects whenever the window or divider size is changed, but I only need to know when the divider position is changed, like when I drag it with the mouse. Is there a way to do that? Any help will be appreciated!

Upvotes: 4

Views: 1776

Answers (1)

DVarga
DVarga

Reputation: 21799

There is no clean way to do this but it is possible for example by using CSS lookup on the SplitPane.

As the dividers have the CSS class of split-pane-divider you can get the dividers from the scene-graph, and they are actually StackPane instances.

On these StackPane you can register a mouse pressed and a mouse release event listener, and update a class member that indicates that the divider is "in a drag" at the moment. And then in the position property listener you can check this class member: if it is true that means that the divider is being moved by the mouse, otherwise the change can be ignored.

Example:

public class Main extends Application {

    // Indicates that the divider is currently dragged by the mouse
    private boolean mouseDragOnDivider = false;

    @Override
    public void start(Stage primaryStage) throws Exception{

        SplitPane sp = new SplitPane();

        sp.getItems().addAll(new StackPane(), new StackPane());
        sp.setDividerPositions(0.3f);

        // Listen to the position property
        sp.getDividers().get(0).positionProperty().addListener((obs, oldVal, newVal) -> {
            if(mouseDragOnDivider)
                System.out.println("It's a mouse drag to pos: " + newVal.doubleValue());
        });

        primaryStage.setScene(new Scene(sp, 300, 275));

        sp.requestLayout();
        sp.applyCss();

        // For each divider register a mouse pressed and a released listener
        for(Node node: sp.lookupAll(".split-pane-divider")) {
            node.setOnMousePressed(evMousePressed -> mouseDragOnDivider = true);
            node.setOnMouseReleased(evMouseReleased -> mouseDragOnDivider = false );
        }

        primaryStage.show();
    }


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

Note: As the lookup only works if the layout is created and the CSS is applied, hence it is important that the requestLayout() and the applyCss() methods are already executed and also that the SplitPane is already added to the scene-graph (attached to a Scene).

Upvotes: 5

Related Questions