如何设置 GridPane 以自动适应 JavaFX 中的内容

How to set a GridPane to adjust automatically to content in JavaFX

我在 ScrollView 里面有一个 GridPane。我在 GridPane 的每个 space 中添加图像。首先只有 1 行和 3 列。但是当我传递 3 张图像的数量时,我在一行中增加了 GridPane 并添加了代表网格行高度的数字 (130px)。所以这是我的代码。

 private void AddItem() {
        ImageView image = new ImageView();
        image.setImage(new Image("media/logo.jpg"));
        image.setFitHeight(50);
        image.setFitWidth(100);
        if (columns > 2) {//when it reaches the end of the columns
            viewGrid.setPrefHeight(viewGrid.getHeight() + 130);//I increase the height of the GridPane
            viewGrid.addRow(rows++);//I add a new row
            columns=0;//I set the column to 0 again
        }

        viewGrid.add(image, columns, rows);
        columns++;
 }

结果

图像开始相互碰撞,而不是保持真实位置:

GridPane 中是否有一些 属性 可以让我实现所需的行为?

不要手动调整 GridPane 的大小。请改用 rowConstraints。这些允许您指定一行的属性,例如对齐和大小约束。 GridPane 会自动更新它的高度。

例子

private static final int COLUMN_COUNT = 3;
private int nextColumnIndex = COLUMN_COUNT;
private int currentRow = -1;

@Override
public void start(Stage primaryStage) {
    Image image = new Image("http://cdn.sstatic.net/Sites/Whosebug/company/img/logos/so/so-icon.png?v=c78bd457575a");
    
    GridPane imagePane = new GridPane();
    
    ColumnConstraints colConstraint = new ColumnConstraints(120);
    colConstraint.setHalignment(HPos.LEFT);
    
    RowConstraints rowConstraints = new RowConstraints(130);
    rowConstraints.setValignment(VPos.CENTER);
    
    // add constraints for columns
    imagePane.getColumnConstraints().addAll(colConstraint, colConstraint, colConstraint);

    ScrollPane scroll = new ScrollPane(imagePane);
    scroll.setFitToWidth(true);
    scroll.setPrefSize(380, 300);

    BorderPane root = new BorderPane(scroll);

    Button btn = new Button("Add Image");
    btn.setOnAction((ActionEvent event) -> {
        ImageView newImage = new ImageView(image);
        newImage.setFitHeight(50);
        newImage.setFitWidth(100);
        if (nextColumnIndex >= COLUMN_COUNT) {
            nextColumnIndex = 0;
            currentRow++;
            imagePane.getRowConstraints().add(rowConstraints);
        }
        imagePane.addRow(currentRow, newImage);
        nextColumnIndex++;
    });

    root.setLeft(new VBox(btn));

    Scene scene = new Scene(root);

    primaryStage.setScene(scene);
    primaryStage.show();
}

顺便说一句:addRow 方法用于将子项添加到特定行,而不是添加行本身。如果将具有索引(或更大索引)的 Node 作为子项添加,则会自动向 GridPane 添加一行。您不需要通过调用 GridPane 方法来创建行。


请注意,与您尝试实现的行为类似的行为已在 FlowPane 中实现。这将是简化代码的一个选项。只需确保 FlowPane 的宽度选择得当(即允许连续 3 个但不允许 4 个元素)。

例子

@Override
public void start(Stage primaryStage) {
    Image image = new Image("http://cdn.sstatic.net/Sites/Whosebug/company/img/logos/so/so-icon.png?v=c78bd457575a");

    FlowPane imagePane = new FlowPane();
    imagePane.setHgap(20);
    imagePane.setVgap(130 - 50);
    imagePane.setRowValignment(VPos.CENTER);
    imagePane.setColumnHalignment(HPos.LEFT);

    ScrollPane scroll = new ScrollPane(imagePane);
    scroll.setFitToWidth(true);
    scroll.setPrefSize(380, 300);

    BorderPane root = new BorderPane(scroll);

    Button btn = new Button("Add Image");
    btn.setOnAction((ActionEvent event) -> {
        ImageView newImage = new ImageView(image);
        newImage.setFitHeight(50);
        newImage.setFitWidth(100);
        imagePane.getChildren().add(newImage);
    });

    root.setLeft(new VBox(btn));

    Scene scene = new Scene(root);

    primaryStage.setScene(scene);
    primaryStage.show();
}