如何在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
相关产品推荐
相关产品推荐

