質問

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();
役に立ちましたか?

解決 2

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.

他のヒント

I had a problem regarding the position of the split pane and it seems similar with yours. Here it is: I have a tabpane, and whenever I add a new tab, I load the content of the tab from an fxml, in which there exists a split pane, with divider position fixed to 0.8.

When the first tab is loaded, it is ok, the divider is positioned at 0.8. When I add the second tab, exactly in the same way with the first tab via fxml, the position of the split pane in the second tab is 0.5, i.e. the default value.

I tried to programatically set the divider position with setDividerPositions method after loading the content of the tab, but it did not work. Then as in your case, if I place the setDividerPositions call in an onAction method, it successfully sets the divider position.

As I stated, my problem is not exactly same as yours, but seems similar. So I am not sure but hope my work around will help you: In my situation, placing the setDividerPositions call in Platform.runLater did the trick.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top