【问题标题】:Distribute remaining space in GridPane or how to do it在 GridPane 中分配剩余空间或如何分配
【发布时间】:2018-06-26 15:02:09
【问题描述】:

我们需要一个具有以下要求的 3 列布局的解决方案:

  • 中间列的大小固定
  • 中间列在父级居中
  • 其他两列共享剩余空间
  • 其他两列的大小相同

假设我们有一个 440 像素的水平空间和一个固定大小为 40 像素的中间列。另外两列应该共享剩余的 400px,这样每列的宽度为 200px。

------------------------------------
|    200px    | 40px |    200px    |
------------------------------------

如果整体尺寸发生变化,比如说500px,中间列的宽度应该不会变化,但其他的应该。

----------------------------------------
|     230px     | 40px |     230px     |
----------------------------------------

如果 GridPane 可以做到这一点,请告诉我怎么做。

如果 GridPane 无法做到这一点,我愿意接受其他建议。

我更喜欢一个简单的解决方案:a)没有 FXML 的 Java 代码和 b)只有 JavaFx,所以需要额外的库。

【问题讨论】:

  • 我猜你的意思是GridPane,而不是GridLayout
  • 是的。我心目中的愚蠢的 Swing 遗产:-D THX

标签: java user-interface javafx gridpane


【解决方案1】:

你只需要三个列约束:

ColumnConstraints leftCol = new ColumnConstraints();
leftCol.setHgrow(Priority.ALWAYS);
ColumnConstraints middleCol = new ColumnConstraints(40);
ColumnConstraints rightCol = new ColumnConstraints();
rightCol.setHgrow(Priority.ALWAYS);

GridPane gridPane = new GridPane();
gridPane.getColumnConstraints().addAll(leftCol, middleCol, rightCol);

如果你愿意,你可以在 FXML 中做同样的事情:

<GridPane>
  <columnConstraints>
    <ColumnConstraints hgrow="ALWAYS"/>
    <ColumnConstraints minWidth="40" prefWidth="40" maxWidth="40"/>
    <ColumnConstraints hgrow="ALWAYS"/>
  </columnConstraints>

  <!-- ... -->
</GridPane>

这是一个 SSCCE:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.stage.Stage;

public class GridPaneTest extends Application {

    @Override
    public void start(Stage primaryStage) {
        ColumnConstraints leftCol = new ColumnConstraints();
        leftCol.setHgrow(Priority.ALWAYS);
        ColumnConstraints middleCol = new ColumnConstraints(40);
        ColumnConstraints rightCol = new ColumnConstraints();
        rightCol.setHgrow(Priority.ALWAYS);


        GridPane gridPane = new GridPane();
        gridPane.getColumnConstraints().addAll(leftCol, middleCol, rightCol);

        Region left = new Region();
        left.setMinHeight(80);
        left.setStyle("-fx-background-color: red;");

        Region middle = new Region();
        middle.setMinHeight(80);
        middle.setStyle("-fx-background-color: green ;");

        Region right = new Region();
        right.setMinHeight(80);
        right.setStyle("-fx-background-color: blue ;");

        gridPane.addRow(0, left, middle, right);

        Scene scene = new Scene(gridPane, 400, 80);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

【讨论】:

  • 这行得通,但我的问题还没有完全解决。我说“中间列有固定大小”。事实上,网格只包含一行,中间列包含一个控件。此控件的大小可以在运行时更改。在您的示例中,绿色区域会改变它的宽度,并且 GridPane 必须对其做出反应。因此,我需要一个详细的解决方案来共享剩余大小而不是动态大小。这不能与约束一起工作,不删除它们,重新计算并“手动”重新添加它们。
  • @Guardian667 我不太明白那个评论。在我的代码中,中间列具有固定大小,正如您在问题中指定的那样:它始终是 40 像素。或者你是说你正在改变问题?
  • 是的,你的例子符合我的解释。关于这个问题,我的解释是不准确的。在我的特殊情况下,列本身并没有被限制为固定大小,而是它的宽度被限制为它包含的控件的大小。 | x |控制 | x |控件的大小可以更改,并且在该更改上剩余空间必须均匀分布。我现在正在通过重新创建约束来做到这一点,当控件的大小发生变化时,但也许有一个更优雅的解决方案。
  • @Guardian667 只需将ColumnConstraints middleCol = new ColumnConstraints(40); 替换为ColumnConstraints middleCol = new ColumnConstraints();? (minmaxprefWidth 默认为 Region.USE_COMPUTED_SIZE。)我认为假设您没有对该列中包含的控件布局进行任何异常操作,这应该可以工作。
  • USE_COMPUTED_SIZE 与 Priority.ALLWAYS 具有相同的效果 :( 我现在的解决方案:中间列的 ColumnConstraints 保存在类参数中。它们的最小值和最大值设置为所需的宽度 i 因为它们变得明显。
猜你喜欢
  • 2017-11-25
  • 1970-01-01
  • 1970-01-01
  • 2017-12-24
  • 1970-01-01
  • 2020-12-20
  • 2011-09-13
  • 1970-01-01
  • 2022-07-21
相关资源
最近更新 更多