You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Scene Builder的VBox中使GridPane保持静态不扩展?

解决JavaFX GridPane随窗口拉伸及Stage适配问题

我来帮你搞定这个问题!要让GridPane保持静态不随窗口扩展,同时让Stage自动适配网格大小,你可以按照下面的步骤来做:

1. 让GridPane保持静态尺寸

默认情况下,GridPane会跟着父容器一起拉伸,我们需要禁用它的自动拉伸行为:

  • 设置GridPane的对齐方式:把GridPane对齐到左上角,避免它在父容器里居中拉伸:

    gridPane.setAlignment(Pos.TOP_LEFT);
    
  • 禁用行列的自动增长:对GridPane的每一行和每一列设置Hgrow和Vgrow为Priority.NEVER,这样行列不会自动扩展:

    // 假设你的网格是rows行cols列
    for (int i = 0; i < cols; i++) {
        ColumnConstraints colConst = new ColumnConstraints();
        colConst.setHgrow(Priority.NEVER);
        colConst.setPrefWidth(cellSize); // 设置每个单元格的固定宽度
        gridPane.getColumnConstraints().add(colConst);
    }
    
    for (int i = 0; i < rows; i++) {
        RowConstraints rowConst = new RowConstraints();
        rowConst.setVgrow(Priority.NEVER);
        rowConst.setPrefHeight(cellSize); // 设置每个单元格的固定高度
        gridPane.getRowConstraints().add(rowConst);
    }
    
  • 固定GridPane的整体大小:也可以直接设置GridPane的prefWidth和prefHeight,确保它不会被拉伸:

    gridPane.setPrefWidth(cols * cellSize + gridPane.getHgap() * (cols - 1));
    gridPane.setPrefHeight(rows * cellSize + gridPane.getVgap() * (rows - 1));
    

2. 生成网格后调整Stage/Scene大小

当你点击按钮生成GridPane后,需要让Stage自动适配网格的大小,这可以通过以下两种方式实现:

方式一:调用Stage的sizeToScene()方法

先把生成好的GridPane设置为Scene的根(或者添加到根容器里),然后让Stage自动适配Scene内容:

// 假设你的Stage是primaryStage,GridPane是dungeonGrid
Scene scene = new Scene(dungeonGrid);
primaryStage.setScene(scene);
primaryStage.sizeToScene(); // 让Stage自动调整大小适配Scene
primaryStage.show();

方式二:手动计算并设置Scene大小

如果GridPane是放在其他容器里(比如BorderPane的center区域),可以计算GridPane的实际大小,然后设置Scene的宽高:

double gridWidth = dungeonGrid.getPrefWidth();
double gridHeight = dungeonGrid.getPrefHeight();
// 如果有其他UI元素(比如你的小按钮),还要加上它们的高度
double totalHeight = gridHeight + button.getPrefHeight() + 20; // 20是间距

Scene scene = new Scene(rootContainer, gridWidthWidth, totalHeight);
primaryStage.setScene(scene);
primaryStage.show();

完整示例代码片段

这里给你一个Controller里的按钮点击事件示例,整合上面的逻辑:

@FXML
private Button smallButton;
@FXML
private BorderPane rootPane; // 假设根容器是BorderPane

private static final int CELL_SIZE = 30;
private static final int SMALL_DUNGEON_ROWS = 10;
private static final int SMALL_DUNGEON_COLS = 10;

@FXML
public void onSmallButtonClick(ActionEvent event) {
    // 创建静态GridPane
    GridPane dungeonGrid = new GridPane();
    dungeonGrid.setHgap(2);
    dungeonGrid.setVgap(2);
    dungeonGrid.setAlignment(Pos.TOP_LEFT);

    // 设置行列约束
    for (int i = 0; i < SMALL_DUNGEON_COLS; i++) {
        ColumnConstraints colConst = new ColumnConstraints();
        colConst.setHgrow(Priority.NEVER);
        colConst.setPrefWidth(CELL_SIZE);
        dungeonGrid.getColumnConstraints().add(colConst);
    }

    for (int i = 0; i < SMALL_DUNGEON_ROWS; i++) {
        RowConstraints rowConst = new RowConstraints();
        rowConst.setVgrow(Priority.NEVER);
        rowConst.setPrefHeight(CELL_SIZE);
        dungeonGrid.getRowConstraints().add(rowConst);
    }

    // 添加网格单元格(比如用Label或者Rectangle)
    for (int row = 0; row < SMALL_DUNGEON_ROWS; row++) {
        for (int col = 0; col < SMALL_DUNGEON_COLS; col++) {
            Rectangle cell = new Rectangle(CELL_SIZE, CELL_SIZE);
            cell.setFill(Color.LIGHTGRAY);
            cell.setStroke(Color.BLACK);
            dungeonGrid.add(cell, col, row);
        }
    }

    // 把GridPane放到根容器的center区域,按钮在top区域
    rootPane.setCenter(dungeonGrid);

    // 调整Stage大小
    Stage stage = (Stage) rootPane.getScene().getWindow();
    // 计算总高度:按钮高度 + 网格高度 + 间距
    double totalHeight = smallButton.getPrefHeight() + dungeonGrid.getPrefHeight() + 10;
    stage.setScene(new Scene(rootPane, dungeonGrid.getPrefWidth(), totalHeight));
    stage.sizeToScene(); // 确保Stage完全适配内容
}

这样处理后,你的GridPane就不会随窗口拉伸了,而且点击按钮后Stage会自动调整到合适的大小,完美适配不同尺寸的地下城网格!

内容的提问来源于stack exchange,提问作者Keithers

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:30:22