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="<<" /> <Button text="<" /> </HBox> <Text text="0.00" GridPane.columnIndex="2" GridPane.rowIndex="4" /> <HBox GridPane.columnIndex="3" GridPane.rowIndex="4"> <Button text=">" /> <Button text=">>" /> </HBox> <Button text="Start" GridPane.columnIndex="2" GridPane.rowIndex="5" /> </GridPane> <stylesheets> <URL value="@style.css" /> </stylesheets> </VBox>
当前布局效果:
解决方案
需要修改三处:
- 让GridPane在VBox中占据全部剩余高度
给GridPane添加VBox.vgrow="ALWAYS"属性,使其自动填充VBox中MenuBar下方的所有剩余空间:
<GridPane hgap="10" vgap="10" VBox.vgrow="ALWAYS">
- 完善GridPane的行约束
原代码仅定义了1个RowConstraints,但GridPane实际有6行,导致只有第一行应用了拉伸规则。需为所有6行添加约束,让SubScene跨行区域获得拉伸空间:
<rowConstraints> <RowConstraints vgrow="ALWAYS" /> <!-- 第0行,让SubScene所在跨行区域拉伸 --> <RowConstraints /> <!-- 第1行 --> <RowConstraints /> <!-- 第2行 --> <RowConstraints /> <!-- 第3行 --> <RowConstraints /> <!-- 第4行 --> <RowConstraints /> <!-- 第5行 --> </rowConstraints>
- 让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="<<" /> <Button text="<" /> </HBox> <Text text="0.00" GridPane.columnIndex="2" GridPane.rowIndex="4" /> <HBox GridPane.columnIndex="3" GridPane.rowIndex="4"> <Button text=">" /> <Button text=">>" /> </HBox> <Button text="Start" GridPane.columnIndex="2" GridPane.rowIndex="5" /> </GridPane> <stylesheets> <URL value="@style.css" /> </stylesheets> </VBox>
内容的提问来源于stack exchange,提问作者George
相关产品推荐
相关产品推荐

