Search code examples
javajavafxjavafx-8javafx-2splitpane

JavaFX Setting SplitPane divider after init regarding components



I want to set my SplitPane divider to a "specific" starting position so, that takes into consideration the components of the window.
There is a fix starter sized TableView, but the window size can be different. So I would like to set the divider position at start so, that the table is fully visible, and right next to it stands the divider.
I have the following code so far in the public void initialize():

Controller:

 @FXML
SplitPane splitPane;

@FXML
TreeTableView treeTable;

public void initialize() {
    getStage().addEventHandler(WindowEvent.WINDOW_SHOWN, new EventHandler<WindowEvent>() {
        @Override
        public void handle(WindowEvent event) {
            double tableWidth = treeTable.getWidth();
            double stageWidth = getStage().getWidth();
            splitPane.setDividerPositions(tableWidth / stageWidth);
        }
    });
}


FXML:

<SplitPane fx:id="splitPane">
    <items>
        <TreeTableView fx:id="treeTable" prefWidth="280">
            <!-- table -->
        </TreeTableView>
        <AnchorPane fx:id="anchorPane">
            <!-- anchor pane -->
        </AnchorPane>
    </items>
</SplitPane>

But it's not working, beacuse the Stage is null at this moment.


Solution

  • So the problem is everything isn't loaded yet so to fix this you can call it at the end of your Main start function as below

    Main:

    public class Main extends Application {
    
        @Override
        public void start(Stage primaryStage) throws Exception{
            FXMLLoader loader = new FXMLLoader(getClass().getResource("/Sample.fxml"));
            Scene scene = new Scene(loader.load());
    
            primaryStage.setScene(scene);
    
            Controller controller = loader.getController();
            controller.setStartingPosition(primaryStage);
    
            primaryStage.show();
        }
    
        public static void main(String[] args) { launch(args); }
    }
    

    Controller:

    public class Controller {
    
        public SplitPane splitPane;
        public TreeTableView treeTable;
        public AnchorPane anchorPane;
    
    
        public void setStartingPosition(Stage stage){
            stage.addEventHandler(WindowEvent.WINDOW_SHOWN, new EventHandler<WindowEvent>() {
                @Override
                public void handle(WindowEvent event) {
                    double tableWidth = treeTable.getWidth();
                    double stageWidth = stage.getWidth();
                    splitPane.setDividerPositions(tableWidth / stageWidth);
                }
            });
        }
    }
    

    I cannot tell if this works as I do not have the "other components" of which you speak so let me know if this works it looks the same both ways for me