在JavaFX中向固定大小的GridPane动态添加元素
我想在JavaFX中显示一个包含不同数量矩形的网格。不能调整此网格的大小,这一点很重要 我选择了在JavaFX中向固定大小的GridPane动态添加元素,java,javafx,gridpane,Java,Javafx,Gridpane,我想在JavaFX中显示一个包含不同数量矩形的网格。不能调整此网格的大小,这一点很重要 我选择了GridPane布局。我动态地向它添加javafx.scene.shape.Rectangle。下面是我的网格的外观,有2行4列 在调整大小时,我希望它保持相同的整体形状,即每个矩形具有相同的大小,并且在我的矩形之间保持水平和垂直间隙 然而,以下是我使用4x4网格得到的结果: 问题是: 最后一行和最后一列的大小与矩形的其余部分不同 这些差距已经消失 以下是我负责刷新显示的代码: public
GridPane
布局。我动态地向它添加javafx.scene.shape.Rectangle
。下面是我的网格的外观,有2行4列
在调整大小时,我希望它保持相同的整体形状,即每个矩形
具有相同的大小,并且在我的矩形
之间保持水平和垂直间隙
然而,以下是我使用4x4网格得到的结果:
问题是:
- 最后一行和最后一列的大小与
矩形的其余部分不同
- 这些差距已经消失
public void refreshConstraints() {
getRowConstraints().clear();
getColumnConstraints().clear();
for (int i = 0; i < nbRow; i++) {
RowConstraints rConstraint = new RowConstraints();
// ((nbRow - 1) * 10 / nbRow) = takes gap into account (10% of height)
rConstraint.setPercentHeight(100 / nbRow - ((nbRow - 1) * 10 / nbRow));
getRowConstraints().add(rConstraint);
}
for (int i = 0; i < nbColumn; i++) {
ColumnConstraints cConstraint = new ColumnConstraints();
cConstraint.setPercentWidth(100 / nbColumn - ((nbColumn - 1) * 10 / nbColumn));
getColumnConstraints().add(cConstraint);
}
}
与网格窗格相比,网格窗格更适合此用例
导入javafx.application.application;
导入javafx.scene.Group;
导入javafx.scene.scene;
导入javafx.scene.control.Label;
导入javafx.scene.control.TextField;
导入javafx.scene.layout.BorderPane;
导入javafx.scene.layout.HBox;
导入javafx.scene.layout.TilePane;
导入javafx.scene.paint.Color;
导入javafx.scene.shape.Rectangle;
导入javafx.stage.stage;
//Java8代码
公共类DynamicTiles扩展了应用程序{
//包含网格的类(见下文)
私有网格显示;
//类负责显示包含矩形的网格
公共类网格显示{
专用静态最终双元素_尺寸=100;
专用静态最终双间隙=元件尺寸/10;
private TilePane TilePane=新TilePane();
专用组显示=新组(tilePane);
私人住宅;
私人国际非政府组织;
公共网格显示(int nRows、int nCols){
设置样式(“-fx背景色:rgba(255,215,0,0.1);”;
tilePane.setHgap(间隙);
tilePane.setVgap(GAP);
设置列(NCOL);
setRows(nRows);
}
公共void setColumns(int newColumns){
nCols=新列;
tilePane.setpref列(ncol);
createElements();
}
public void setRows(int newRows){
nRows=新行;
tilePane.setPrefRows(nRows);
createElements();
}
公共组getDisplay(){
返回显示;
}
私有void createElements(){
tilePane.getChildren().clear();
对于(int i=0;i{
如果(!t1){
如果(!rowField.getText().equals(“”){
试一试{
int nbRow=Integer.parseInt(rowField.getText());
gridDisplay.setRows(nbRow);
}捕获(NumberFormatException nfe){
System.out.println(“请输入有效数字”);
}
}
}
});
columnField.focusedProperty().addListener((ov,t,t1)->{
如果(!t1){
如果(!columnField.getText()等于(“”){
试一试{
int-nbColumn=Integer.parseInt(columnField.getText());
gridDisplay.setColumns(nbColumn);
}捕获(NumberFormatException nfe){
System.out.println(“请输入有效数字”);
}
}
}
});
}
}
非常感谢您的回答TilePane
s确实更易于使用,尽管您所写的并不能完全回答我的问题
我想要一个窗格,其中的子项可以调整大小,而不是窗格本身。设置maxSize
和prefSize
似乎没有任何效果
编辑:我在我的GridDisplay
类中使用了两个JavaFX属性
,对应于固定的网格高度和宽度:
public class GridDisplay {
private ReadOnlyDoubleProperty heightProperty;
private ReadOnlyDoubleProperty widthProperty;
...
}
然后,我将与构造函数中所需的固定大小相对应的值分配给这些成员。栅格中的子对象的大小相当于栅格高度和宽度的一小部分
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.TilePane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
// java 8 code
public class DynamicTiles extends Application {
//Class containing grid (see below)
private GridDisplay gridDisplay;
//Class responsible for displaying the grid containing the Rectangles
public class GridDisplay {
private static final double ELEMENT_SIZE = 100;
private static final double GAP = ELEMENT_SIZE / 10;
private TilePane tilePane = new TilePane();
private Group display = new Group(tilePane);
private int nRows;
private int nCols;
public GridDisplay(int nRows, int nCols) {
tilePane.setStyle("-fx-background-color: rgba(255, 215, 0, 0.1);");
tilePane.setHgap(GAP);
tilePane.setVgap(GAP);
setColumns(nCols);
setRows(nRows);
}
public void setColumns(int newColumns) {
nCols = newColumns;
tilePane.setPrefColumns(nCols);
createElements();
}
public void setRows(int newRows) {
nRows = newRows;
tilePane.setPrefRows(nRows);
createElements();
}
public Group getDisplay() {
return display;
}
private void createElements() {
tilePane.getChildren().clear();
for (int i = 0; i < nCols; i++) {
for (int j = 0; j < nRows; j++) {
tilePane.getChildren().add(createElement());
}
}
}
private Rectangle createElement() {
Rectangle rectangle = new Rectangle(ELEMENT_SIZE, ELEMENT_SIZE);
rectangle.setStroke(Color.ORANGE);
rectangle.setFill(Color.STEELBLUE);
return rectangle;
}
}
@Override
public void start(Stage primaryStage) {
//Represents the grid with Rectangles
gridDisplay = new GridDisplay(2, 4);
//Fields to specify number of rows/columns
TextField rowField = new TextField("2");
TextField columnField = new TextField("4");
//Function to set an action when text field loses focus
buildTextFieldActions(rowField, columnField);
HBox fields = new HBox(10);
fields.getChildren().add(rowField);
fields.getChildren().add(new Label("x"));
fields.getChildren().add(columnField);
BorderPane mainPanel = new BorderPane();
mainPanel.setCenter(gridDisplay.getDisplay());
mainPanel.setTop(fields);
Scene scene = new Scene(mainPanel, 1000, 800);
primaryStage.setTitle("Test grid display");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
private void buildTextFieldActions(final TextField rowField, final TextField columnField) {
rowField.focusedProperty().addListener((ov, t, t1) -> {
if (!t1) {
if (!rowField.getText().equals("")) {
try {
int nbRow = Integer.parseInt(rowField.getText());
gridDisplay.setRows(nbRow);
} catch (NumberFormatException nfe) {
System.out.println("Please enter a valid number.");
}
}
}
});
columnField.focusedProperty().addListener((ov, t, t1) -> {
if (!t1) {
if (!columnField.getText().equals("")) {
try {
int nbColumn = Integer.parseInt(columnField.getText());
gridDisplay.setColumns(nbColumn);
} catch (NumberFormatException nfe) {
System.out.println("Please enter a valid number.");
}
}
}
});
}
}
public class GridDisplay {
private ReadOnlyDoubleProperty heightProperty;
private ReadOnlyDoubleProperty widthProperty;
...
}
public void updateDisplay() {
gridPane.getChildren().clear();
for (int i = 0; i < nbColumn; i++) {
for (int j = 0; j < nbRow; j++) {
Rectangle rectangle = new Rectangle(100, 100);
//Binding the fraction of the grid size to the width
//and heightProperty of the child
rectangle.widthProperty().bind(widthProperty.divide(nbColumn));
rectangle.heightProperty().bind(heightProperty.divide(nbRow));
gridPane.add(rectangle, i, j);
}
}
}