Javafx 设置SplitPane的分隔符位置
我想将拆分窗格的分隔符设置为某个默认位置。这不起作用,分隔器停留在中间:Javafx 设置SplitPane的分隔符位置,javafx,javafx-8,Javafx,Javafx 8,我想将拆分窗格的分隔符设置为某个默认位置。这不起作用,分隔器停留在中间: 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).positionP
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
它表明有什么东西将它重置到中间
我怎样才能做到这一点呢?试试看
splitPane.setDividerPosition(0, percentage);
参数设置为dividerposition(int dividerIndex,双百分比)问题似乎是在
阶段最大化期间设置拆分窗格
宽度时,会重置分隔器位置。随后通过收听窗口的showing属性设置分隔符位置,如下所示:
primaryStage.showingProperty().addListener(新的ChangeListener()){
@凌驾
在阶段
初始化过程中,公共空隙发生了变化(可观察值),窗口大小多次变化,直到布局完成。每次变化都会修改分隔器位置。如果要控制分隔器位置,则必须在阶段
完全初始化后进行设置:
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;
}
private boolean m_stageshow=false;
@凌驾
public void start(Stage primaryStage)引发异常{
SplitPane SplitPane=new SplitPane(new Pane(),new Pane());
ChangeListener ChangeListener=新的ChangeListener(){
@凌驾
public void changed(observevalue我有同样的问题,上面的解决方案对我来说不可靠。
因此,我为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(新DumbSplitPaneSkin(SplitPane));您只需使用
Platform.runLater(new Runnable() {
@Override
public void run() {
splitPane.setDividerPositions(0.8);
}
});
Platform.runLater(新的Runnable(){
@凌驾
公开募捐{
splitPane.setDividerPositions(0.8);
}
});
这不是100%可靠的解决方案,因为run()
方法在JFX线程中未指定的时间执行,但对于简单的初始化情况,它可以正常工作。以下是我的结果:
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();
}
}
导入javafx.application.application;
导入javafx.event.ActionEvent;
导入javafx.event.EventHandler;
导入javafx.geometry.Orientation;
导入javafx.scene.*;
导入javafx.scene.control.*;
导入javafx.scene.layout.*;
导入javafx.scene.paint.Color;
导入javafx.stage.*;
/**
*拆分窗格,对话框示例
*@作者Pataki István
*/
公共类SimpleDock扩展了应用程序{
私有双拆分位置=0;
private SplitPane rootPane=new SplitPane();
私人对话;
私人边境区;
@凌驾
public void start(final Stage)引发异常{
根窗格。设置方向(方向。垂直);
根窗格.setOrder(新边框)(新边框笔划(
颜色,绿色,
BorderStrokeStyle.SOLID,
新的转弯半径(5),
新边框宽度(3))
));
dockedArea=新边框窗格(新文本区域(“某些停靠内容”);
最终流程窗格中心区域=新流程窗格();
最终按钮解锁按钮=新按钮(“解锁”);
centerArea.getChildren().add(撤消按钮);
rootPane.getItems().addAll(centerArea,dockedArea);
舞台场景(新场景(根窗格,300300));
stage.show();
dialog=新建MyDialog(阶段);
undockButton.disableProperty().bind(dialog.showingProperty());
撤销Button.setOnAction(新的EventHandler(){
@凌驾
公共无效句柄(ActionEvent ActionEvent){
处理者(阶段);
}
});
}
专用void处理程序(阶段){
splitPosition=rootPane.getDividerPositions()[0];
rootPane.getItems().remove(dockedArea);
对话框.setOnHidden(windowEvent->{
rootPane.getItems().add(dockedArea);
rootPane.setDividerPositions(splitPosition);
});
dialog.setContent(dockdarea);
对话.表演(舞台);
}
私有类MyDialog扩展弹出窗口{
私有边界根;
私有MyDialog(窗口父级){
root=新边框窗格();
root.setPrefSize(200200);
root.setStyle(“-fx边框宽度:1;-fx边框颜色:灰色”);
setTop(buildTitleBar());
setX(parent.getX()+50);
setY(parent.getY()+50);
getContent().add(根目录);
}
公共内容(节点内容){
root.setCenter(内容);
}
私有节点buildTitleBar(){
BorderPane=新的BorderPane();
窗格设置样式(“-fx背景色:burlywood;-fx填充:5”);
最终增量dragDelta=新增量();
pane.setOnMousePressed(鼠标事件->{
dragDelta.x=getX()-mouseEvent.getScreenX();
dragDelta.y=getY()-mouseEvent.getScreenY();
});
pane.setonMouseDrawed(mouseEvent->{
setX(mouseEvent.getScreenX()+dragDelta.x);
setY(mouseEvent.getScreenY()+dragDelta.y);
});
标签标题=新标签(“我的对话框”);
title.setStyle(“-fx文本填充:午夜蓝;”);
窗格。设置左(标题);
按钮关闭按钮=新按钮(“X”);
setOnAction(actionEvent->hide());
窗格。设置右键(关闭按钮);
返回窗格;
}
}
私有静态类增量{
双x,y;
}
公共静态void main(字符串[]args)引发异常{
发射();
}
}
这是您希望的工作方式。因为您通常在splitpane中至少有一些内容,例如vbox,只需设置最小和最大宽度,它就会自动设置分隔器。正如其他人指出的,问题是当舞台最大化时,分隔器位置会重置
您可以通过将resizeableWithParent
设置为false
来防止这种情况
示例
假设您有一个SplitPane
,其中包含两个嵌套容器。以下是fxml摘录:
<SplitPane fx:id="splitPane" dividerPositions="0.25">
<VBox fx:id="leftSplitPaneContainer" />
<FlowPane fx:id="rightSplitPaneContainer"/>
</SplitPane>
然后,您只需在两个容器上调用SplitPane.setResizeableWithParent()
,即可防止重置t
@FXML
private SplitPane splitPane;
@FXML
private VBox leftSplitPaneContainer;
@FXML
private FlowPane rightSplitPaneContainer;
public void initialize(){
SplitPane.setResizableWithParent(leftSplitPaneContainer, false);
SplitPane.setResizableWithParent(rightSplitPaneContainer, false);
}