可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I want to set the divider of a SplitPane to a certain default position. This does not work, the divider stays in the middle:
public void start(Stage primaryStage) throws Exception{ SplitPane splitPane = new SplitPane(new Pane(), new Pane()); // Report changes to the divider position splitPane.getDividers().get(0).positionProperty().addListener( o -> System.out.println(splitPane.getDividerPositions()[0]) ); // Doesn't work: splitPane.setDividerPositions(0.8); // The docs seem to recommend the following (with floats instead of // doubles, and with one number more than there are dividers, which is // weird), but it doesn't work either: //splitPane.setDividerPositions(0.8f, 0.2f); primaryStage.setScene(new Scene(splitPane)); primaryStage.setMaximized(true); primaryStage.show(); }
The output:
0.8 0.5

It suggests that something resets it to the middle.
How can I achieve this?
回答1:
The issue seems to be the divider position being reset when the width of the SplitPane is set during the maximizing of the Stage. You should be able to set it afterwards by listening to the showing property of the window:
primaryStage.showingProperty().addListener(new ChangeListener<Boolean>() { @Override public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { if (newValue) { splitPane.setDividerPositions(0.8); observable.removeListener(this); } } });
回答2:
During Stage initialization, window size changes several times until layout is completed. Every change modifies divider positions. If you want to control divider positions, they have to be set after Stage is fully initialized:
private boolean m_stageShowing = false; @Override public void start(Stage primaryStage) throws Exception { SplitPane splitPane = new SplitPane(new Pane(), new Pane()); ChangeListener<Number> changeListener = new ChangeListener<Number>() { @Override public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { splitPane.setDividerPositions(0.8); if (m_stageShowing) { observable.removeListener(this); } } }; splitPane.widthProperty().addListener(changeListener); splitPane.heightProperty().addListener(changeListener); primaryStage.setScene(new Scene(splitPane)); primaryStage.setMaximized(true); primaryStage.show(); m_stageShowing = true; }
回答3:
I had the same problem and the above solutions where not working reliably for me. So I created a custom skin for SplitPane:
public class DumbSplitPaneSkin extends SplitPaneSkin { public DumbSplitPaneSkin(SplitPane splitPane) { super(splitPane); } @Override protected void layoutChildren(double x, double y, double w, double h) { double[] dividerPositions = getSkinnable().getDividerPositions(); super.layoutChildren(x, y, w, h); getSkinnable().setDividerPositions(dividerPositions); } }
This skin can be used via css or by overriding SplitPane.createDefaultSkin(). You can also set programatically as splitPane.setSkin(new DumbSplitPaneSkin(splitPane));
回答4:
You could just wrap the call setDividerPositions with
Platform.runLater(new Runnable() { @Override public void run() { splitPane.setDividerPositions(0.8); } }); This is not 100% reliable solution because run() method is performed in JFX thread at unspecified time but it works properly for simple initialization cases.
回答5:
Try
splitPane.setDividerPosition(0, percentage);
The parameters are setDividerPosition(int dividerIndex, double percentage)