我想将SplitPane的分隔符设置为某个默认位置。这不起作用,分隔线保持在中间:
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();
}
输出:
0.8
0.5
它表明某些东西会重置到中间。
我怎样才能做到这一点?
答案 0 :(得分:9)
问题似乎是在最大化SplitPane
期间设置Stage
的宽度时重置分隔符位置。您应该可以通过监听窗口的showing
属性来设置它:
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);
}
}
});
答案 1 :(得分:0)
在Stage
初始化期间,窗口大小会多次更改,直到布局完成。每次更改都会修改分隔符位置。如果要控制分隔符位置,则必须在 Stage
完全初始化后设置:
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;
}
答案 2 :(得分:0)
我遇到了同样的问题,上面的解决方案对我来说不可靠。 所以我为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);
}
}
此皮肤可以通过css或重写SplitPane.createDefaultSkin()来使用。您还可以以编程方式设置为splitPane.setSkin(new DumbSplitPaneSkin(splitPane));
答案 3 :(得分:0)
您可以使用
打包电话setDividerPositions
Platform.runLater(new Runnable() { @Override public void run() { splitPane.setDividerPositions(0.8); } });
这不是100%可靠的解决方案,因为run()
方法在未指定的时间在JFX线程中执行,但它适用于简单的初始化情况。
答案 4 :(得分:0)
这是我的结果:
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Orientation;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.*;
/**
* SplitPane, Dialogbox example
* @author Pataki István
*/
public class SimpleDocking extends Application {
private double splitPosition = 0;
private SplitPane rootPane = new SplitPane();
private MyDialog dialog;
private BorderPane dockedArea;
@Override
public void start(final Stage stage) throws Exception {
rootPane.setOrientation(Orientation.VERTICAL);
rootPane.setBorder(new Border(new BorderStroke(
Color.GREEN,
BorderStrokeStyle.SOLID,
new CornerRadii(5),
new BorderWidths(3))
));
dockedArea = new BorderPane(new TextArea("Some docked content"));
final FlowPane centerArea = new FlowPane();
final Button undockButton = new Button("Undock");
centerArea.getChildren().add(undockButton);
rootPane.getItems().addAll(centerArea, dockedArea);
stage.setScene(new Scene(rootPane, 300, 300));
stage.show();
dialog = new MyDialog(stage);
undockButton.disableProperty().bind(dialog.showingProperty());
undockButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
handler(stage);
}
});
}
private void handler(Stage stage) {
splitPosition = rootPane.getDividerPositions()[0];
rootPane.getItems().remove(dockedArea);
dialog.setOnHidden(windowEvent -> {
rootPane.getItems().add(dockedArea);
rootPane.setDividerPositions(splitPosition);
});
dialog.setContent(dockedArea);
dialog.show(stage);
}
private class MyDialog extends Popup {
private BorderPane root;
private MyDialog(Window parent) {
root = new BorderPane();
root.setPrefSize(200, 200);
root.setStyle("-fx-border-width: 1; -fx-border-color: gray");
root.setTop(buildTitleBar());
setX(parent.getX() + 50);
setY(parent.getY() + 50);
getContent().add(root);
}
public void setContent(Node content) {
root.setCenter(content);
}
private Node buildTitleBar() {
BorderPane pane = new BorderPane();
pane.setStyle("-fx-background-color: burlywood; -fx-padding: 5");
final Delta dragDelta = new Delta();
pane.setOnMousePressed(mouseEvent -> {
dragDelta.x = getX() - mouseEvent.getScreenX();
dragDelta.y = getY() - mouseEvent.getScreenY();
});
pane.setOnMouseDragged(mouseEvent -> {
setX(mouseEvent.getScreenX() + dragDelta.x);
setY(mouseEvent.getScreenY() + dragDelta.y);
});
Label title = new Label("My Dialog");
title.setStyle("-fx-text-fill: midnightblue;");
pane.setLeft(title);
Button closeButton = new Button("X");
closeButton.setOnAction(actionEvent -> hide());
pane.setRight(closeButton);
return pane;
}
}
private static class Delta {
double x, y;
}
public static void main(String[] args) throws Exception {
launch();
}
}
这是您想要的作品。
答案 5 :(得分:0)
因为您通常至少在 splitpane 中有一些东西,例如。 vbox,只需设置最小和最大宽度,它就会自动设置分隔线。
答案 6 :(得分:0)
正如其他人所指出的,问题是当舞台最大化时分隔线位置会被重置。
您可以通过将 ResizableWithParent
设置为 false
来防止这种情况发生。
示例
假设您有一个 SplitPane
,里面有两个嵌套的容器。这是 fxml 摘录:
<SplitPane fx:id="splitPane" dividerPositions="0.25">
<VBox fx:id="leftSplitPaneContainer" />
<FlowPane fx:id="rightSplitPaneContainer"/>
</SplitPane>
这里是控制器类的摘录:
@FXML
private SplitPane splitPane;
@FXML
private VBox leftSplitPaneContainer;
@FXML
private FlowPane rightSplitPaneContainer;
然后您只需在两个容器上调用 SplitPane.setResizableWithParent()
以防止重置分隔符位置:
public void initialize(){
SplitPane.setResizableWithParent(leftSplitPaneContainer, false);
SplitPane.setResizableWithParent(rightSplitPaneContainer, false);
}
即使最大化窗口,分隔线位置现在也将保持在 0.25。
不涉及复杂的侦听器或覆盖 SplitPaneSkin
。
答案 7 :(得分:-3)
尝试
splitPane.setDividerPosition(0, percentage);
参数是setDividerPosition(int dividerIndex,double percentage)