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

JavaFX FXML:如何使GridPane与父容器VBox高度一致?

问题

需要让位于(0,0)位置的SubScene元素填满GridPane周围的空白区域。横向使用hgrow="always"可实现自适应,但纵向vgrow="always"无效。已确认GridPane所在的VBox已占据舞台全部高度,问题出在GridPane本身。

附上FXML代码:

<?xml version="1.0" encoding="UTF-8"?>

<?import java.net.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.SubScene?>
<?import javafx.scene.Group?>

<VBox
    fx:controller="Controller" 
    xmlns:fx="http://javafx.com/fxml"
    styleClass="root" >
    
    <MenuBar>
        <menus>
            <Menu text="File">
                <items>
                    <MenuItem text="New" />
                    <MenuItem text="Save" />
                    <MenuItem text="Load" />
                </items>
            </Menu>
        </menus>
    </MenuBar>
    
    <GridPane hgap="10" vgap="10">
    
        <rowConstraints>
            <RowConstraints vgrow="ALWAYS" />
        </rowConstraints>
        
        <columnConstraints>
            <ColumnConstraints hgrow="ALWAYS" />
        </columnConstraints>
    
        <gridLinesVisible>true</gridLinesVisible>
        
        <SubScene
            GridPane.columnIndex="0" GridPane.rowIndex="0"
            GridPane.rowSpan="6">
            
            <root>
            <Group />
            </root>
            
        </SubScene>
            
        <Button text="Add"
            GridPane.columnIndex="1" GridPane.rowIndex="0" />
            
        <Button text="Edit"
            GridPane.columnIndex="2" GridPane.rowIndex="0" />
            
        <Button text="Delete"
            GridPane.columnIndex="3" GridPane.rowIndex="0" />
            
        <ScrollPane 
            GridPane.columnIndex="1" GridPane.rowIndex="1"
            GridPane.columnSpan="3" />
            
        <Label text="Speed"
            GridPane.columnIndex="1" GridPane.rowIndex="2" />
            
        <Slider
            GridPane.columnIndex="2" GridPane.rowIndex="2" 
            GridPane.columnSpan="2" />
            
        <Label text="Gravity"
            GridPane.columnIndex="1" GridPane.rowIndex="3" />
            
        <TextField
            GridPane.columnIndex="2" GridPane.rowIndex="3" 
            GridPane.columnSpan="2" />
            
        <HBox
            GridPane.columnIndex="1" GridPane.rowIndex="4">
            <Button text="&lt;&lt;" />
            <Button text="&lt;" />
        </HBox>
        
        <Text text="0.00" 
            GridPane.columnIndex="2" GridPane.rowIndex="4" />
        
        <HBox
            GridPane.columnIndex="3" GridPane.rowIndex="4">
            <Button text="&gt;" />
            <Button text="&gt;&gt;" />
        </HBox>
        
        <Button text="Start" 
            GridPane.columnIndex="2" GridPane.rowIndex="5" />
        
    </GridPane>
    
    <stylesheets>
        <URL value="@style.css" />
    </stylesheets>  

</VBox>

当前布局效果:
当前布局效果

解决方案

需要修改三处:

  1. 让GridPane在VBox中占据全部剩余高度
    给GridPane添加VBox.vgrow="ALWAYS"属性,使其自动填充VBox中MenuBar下方的所有剩余空间:
<GridPane hgap="10" vgap="10" VBox.vgrow="ALWAYS">
  1. 完善GridPane的行约束
    原代码仅定义了1个RowConstraints,但GridPane实际有6行,导致只有第一行应用了拉伸规则。需为所有6行添加约束,让SubScene跨行区域获得拉伸空间:
<rowConstraints>
    <RowConstraints vgrow="ALWAYS" /> <!-- 第0行,让SubScene所在跨行区域拉伸 -->
    <RowConstraints /> <!-- 第1行 -->
    <RowConstraints /> <!-- 第2行 -->
    <RowConstraints /> <!-- 第3行 -->
    <RowConstraints /> <!-- 第4行 -->
    <RowConstraints /> <!-- 第5行 -->
</rowConstraints>
  1. 让SubScene填充所在单元格
    给SubScene添加GridPane.fillWidth="true"和GridPane.fillHeight="true"属性,确保它填满分配的GridPane单元格空间:
<SubScene
    GridPane.columnIndex="0" GridPane.rowIndex="0"
    GridPane.rowSpan="6"
    GridPane.fillWidth="true"
    GridPane.fillHeight="true">

修改后的完整FXML代码:

<?xml version="1.0" encoding="UTF-8"?>

<?import java.net.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.SubScene?>
<?import javafx.scene.Group?>

<VBox
    fx:controller="Controller" 
    xmlns:fx="http://javafx.com/fxml"
    styleClass="root" >
    
    <MenuBar>
        <menus>
            <Menu text="File">
                <items>
                    <MenuItem text="New" />
                    <MenuItem text="Save" />
                    <MenuItem text="Load" />
                </items>
            </Menu>
        </menus>
    </MenuBar>
    
    <GridPane hgap="10" vgap="10" VBox.vgrow="ALWAYS">
    
        <rowConstraints>
            <RowConstraints vgrow="ALWAYS" />
            <RowConstraints />
            <RowConstraints />
            <RowConstraints />
            <RowConstraints />
            <RowConstraints />
        </rowConstraints>
        
        <columnConstraints>
            <ColumnConstraints hgrow="ALWAYS" />
        </columnConstraints>
    
        <gridLinesVisible>true</gridLinesVisible>
        
        <SubScene
            GridPane.columnIndex="0" GridPane.rowIndex="0"
            GridPane.rowSpan="6"
            GridPane.fillWidth="true"
            GridPane.fillHeight="true">
            
            <root>
            <Group />
            </root>
            
        </SubScene>
            
        <Button text="Add"
            GridPane.columnIndex="1" GridPane.rowIndex="0" />
            
        <Button text="Edit"
            GridPane.columnIndex="2" GridPane.rowIndex="0" />
            
        <Button text="Delete"
            GridPane.columnIndex="3" GridPane.rowIndex="0" />
            
        <ScrollPane 
            GridPane.columnIndex="1" GridPane.rowIndex="1"
            GridPane.columnSpan="3" />
            
        <Label text="Speed"
            GridPane.columnIndex="1" GridPane.rowIndex="2" />
            
        <Slider
            GridPane.columnIndex="2" GridPane.rowIndex="2" 
            GridPane.columnSpan="2" />
            
        <Label text="Gravity"
            GridPane.columnIndex="1" GridPane.rowIndex="3" />
            
        <TextField
            GridPane.columnIndex="2" GridPane.rowIndex="3" 
            GridPane.columnSpan="2" />
            
        <HBox
            GridPane.columnIndex="1" GridPane.rowIndex="4">
            <Button text="&lt;&lt;" />
            <Button text="&lt;" />
        </HBox>
        
        <Text text="0.00" 
            GridPane.columnIndex="2" GridPane.rowIndex="4" />
        
        <HBox
            GridPane.columnIndex="3" GridPane.rowIndex="4">
            <Button text="&gt;" />
            <Button text="&gt;&gt;" />
        </HBox>
        
        <Button text="Start" 
            GridPane.columnIndex="2" GridPane.rowIndex="5" />
        
    </GridPane>
    
    <stylesheets>
        <URL value="@style.css" />
    </stylesheets>  

</VBox>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 02:10:50