I have two StackPanes (pane1 & pane2) being displayed in a SplitPane (splitPane). The SplitPane's divider position is set to .3 in the builder. The seond StackPane (pane2) contains a Button which also sets the SplitPane's divider position to .3.
Ceteris paribus, the expected behaviour would be that both actions (setting the divider position in the builder & setting the divider position through an action) either work or not.
Yet, only the latter actually works.
What changes between the construction of the SplitPane and the onAction of the Button. What hinders the placement of the divider in the builder?
StackPane pane1 = new StackPane();
StackPane pane2 = new StackPane();
final SplitPane splitPane = SplitPaneBuilder.create()
.items(pane1, pane2)
// Environment A
.dividerPositions(new double[] {.3}) // splitPane.setDividerPosition(s)(...), etc. yield same result
.orientation(Orientation.HORIZONTAL)
.build();
// The following line influences environment A outcome, though it does not fix the issue
SplitPane.setResizableWithParent(pane1, false);
pane2.getChildren().add(ButtonBuilder.create()
.text("Divider Position")
.onAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
// Environment B
splitPane.setDividerPositions(.3);
}
})
.build());
Scene primaryScene = SceneBuilder.create()
.root(splitPane)
.build();
primaryStage.setScene(primaryScene);
primaryStage.setTitle("Name");
primaryStage.setWidth(500);
primaryStage.setHeight(500);
primaryStage.show();
So, thanks to James D in the Oracle support forums, here is the full answer:
"The issue appears to be that the scene's size is smaller than that of its window. This causes an additional layout pass when the window is first displayed; the second layout pass counts as a "window resize" and consequently the divider position of the split pane is not respected on this pass." (https://forums.oracle.com/forums/thread.jspa?threadID=2503701)
Workaround 1
Set the Scene
's size instead of the Stage
's size:
Scene primaryScene = SceneBuilder.create()
.root(splitPane)
.width(500)
.height(500)
.build();
primaryStage.setScene(primaryScene);
primaryStage.setTitle("Name");
primaryStage.show();
Workaround 2
As Ramazan has correctly pointed out, another solution would be to set the divider position in Platform.runLater(...)
.
Followups
I have filed a bug at jira (http://javafx-jira.kenai.com/browse/RT-28607), referencing the original bug report (http://javafx-jira.kenai.com/browse/RT-17229) which had been marked "unresolveable". I guess the final solution would be to provide methods for the absolute positioning of the divider.