【问题标题】:Fill width in a Pane在窗格中填充宽度
【发布时间】:2015-10-29 12:24:04
【问题描述】:

有一个Pane 作为根,一个GridPane 作为它的子级。根随舞台调整大小。我怎样才能实现GridPane 自动随根调整大小以填充宽度? 任何宽度都可以。是否可以不绑定属性?

情况是这样的:

  1. Pane (黄色)是Scene 的根,因此它填充了Stage 的宽度和高度。
  2. GridPane(绿色)作为 root 的子级,其中一行 3 列。
  3. 该行应该有一个固定的高度。
  4. 第一列和第三列的大小应保持不变
  5. 中间的列应该增长到最大值
  6. GridPane 应填充其父级的宽度

不幸的是,GridPane 没有填满宽度:

代码:

@Override
public void start(Stage primaryStage) throws Exception {
    // Resizes with the stage
    final Pane root = new Pane();
    root.setStyle("-fx-background-color: yellow");

    // grid: 1 row, 3 colums
    // should have a constant height and should grow in width to fill parent pane
    final GridPane gridPane = new GridPane();
    root.getChildren().add(gridPane);
    gridPane.setStyle("-fx-background-color: green");
    gridPane.setGridLinesVisible(true);

    final RowConstraints row = new RowConstraints(100); // constant height = 100
    final ColumnConstraints col1 = new ColumnConstraints(100, Control.USE_COMPUTED_SIZE, Control.USE_COMPUTED_SIZE);
    // should grow as much as possible in width
    final ColumnConstraints col2 = new ColumnConstraints(200, Control.USE_COMPUTED_SIZE, Double.MAX_VALUE);
    final ColumnConstraints col3 = new ColumnConstraints(100, Control.USE_COMPUTED_SIZE, Control.USE_COMPUTED_SIZE);
    gridPane.getRowConstraints().add(row);
    gridPane.getColumnConstraints().addAll(col1, col2, col3);

    final Scene scene = new Scene(root);
    primaryStage.setScene(scene);
    primaryStage.setWidth(600);
    primaryStage.setHeight(400);
    primaryStage.show();
}

【问题讨论】:

    标签: java layout javafx


    【解决方案1】:

    窗格内节点的大小由单个窗格实现其布局的方式控制:即节点的大小实际上由其父级确定。因此,网格窗格的整体大小由 Pane 的布局实现控制。

    Pane 实际上做了最少的布局工作:它实际上只是将所有内容定位在 (0,0) 并将其调整为首选大小。因此,您的网格窗格将获得其首选宽度,即各列首选宽度的总和。

    因此,要让您的网格窗格增长,您要么需要更改其首选宽度,要么使用允许您控制其增长方式的布局窗格。

    例如:

    gridPane.prefWidthProperty().bind(root.widthProperty());
    

    将使网格窗格增长到根的宽度。这只会在所有三列的右侧添加额外的空间,因此另外设置

    col2.setHgrow(Priority.ALWAYS);
    

    会让col2有额外的宽度。

    或者,将AnchorPane 用于root

    // Pane root = new Pane();
    AnchorPane root = new AnchorPane();
    

    和设置

    AnchorPane.setLeftAnchor(gridPane, 0.0);
    AnchorPane.setRightAnchor(gridPane, 0.0);
    

    (再次使用col2 hgrow 设置)将具有相同的效果。

    或者你可以这样做

    VBox root = new VBox();
    root.setFillWidth(true);
    

    (例如:有很多解决方案)。

    解决方案的选择取决于根窗格中的其他节点(如果有)。

    【讨论】:

      【解决方案2】:

      Pane 不会自动布局其子级。尝试改用VBox。它将通过(如果可能)调整其子项的大小来填充可用空间的宽度。这样,GridPane 将根据舞台宽度的变化调整大小。

      现在,您可以管理网格窗格列如何共享空间。根据你的描述设置就够了

      col2.setHgrow( Priority.ALWAYS );
      

      【讨论】:

      • James_D 更快,但 +1 :)
      【解决方案3】:

      要使网格窗格自动调整,请使用 fxml。不要用java来做。

      见下文,它们被设置为百分比宽度。下面我的示例中的最后一行具有固定设置。

      <GridPane fx:id="gridPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="500.0" prefWidth="700.0" xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
      
        <columnConstraints>
          <ColumnConstraints percentWidth="50" /> 
          <ColumnConstraints percentWidth="50" />
        </columnConstraints>
        <rowConstraints>
          <RowConstraints percentHeight="35" />
          <RowConstraints percentHeight="35" />
          <RowConstraints maxHeight="106.0" minHeight="10.0" prefHeight="106.0" vgrow="ALWAYS" />
        </rowConstraints>
         <children>
      

      【讨论】:

        【解决方案4】:

        其实你的结果就是预期的100 + 200 + 100 = 400px

        final ColumnConstraints col1 = new ColumnConstraints(100, Control.USE_COMPUTED_SIZE, Control.USE_COMPUTED_SIZE);
        //                                                   ↑
        final ColumnConstraints col2 = new ColumnConstraints(200, Control.USE_COMPUTED_SIZE, Double.MAX_VALUE);
        //                                                   ↑
        final ColumnConstraints col3 = new ColumnConstraints(100, Control.USE_COMPUTED_SIZE, Control.USE_COMPUTED_SIZE);
        //                                                   ↑
        

        你定义:

        primaryStage.setWidth(600);
        

        只需更改 medium 列以填充其余部分 200px

        final ColumnConstraints col1 = new ColumnConstraints(100, Control.USE_COMPUTED_SIZE, Control.USE_COMPUTED_SIZE);
        final ColumnConstraints col2 = new ColumnConstraints(400, Control.USE_COMPUTED_SIZE, Double.MAX_VALUE);
        //                                                   ↑ change to 400
        final ColumnConstraints col3 = new ColumnConstraints(100, Control.USE_COMPUTED_SIZE, Control.USE_COMPUTED_SIZE);
        

        【讨论】:

        • 谢谢,这将是根的恒定宽度的答案。但我希望 GridPane 的宽度动态增长。所以它应该适用于任何宽度。
        猜你喜欢
        • 1970-01-01
        • 2011-09-05
        • 1970-01-01
        • 2022-11-22
        • 2015-12-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多