Set divider position of SplitPane

匿名 (未验证) 提交于 2019-12-03 00:56:02

问题:

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)



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!