JavaFX GridPane 正在调整大小而不是使用新数量的约束保持位置

JavaFX GridPane is resizing instead of holding position with new amount of Constraints

我的任务是创建一个 UI,左侧是导航选项卡,右侧是网格窗格(向下滚动 ui)。 首先,我通过向其添加 Row- 和 Columnconstraints 来初始化网格。首次启动程序后,它完全可以正常工作。

看起来像:

在按下具有更新值的应用按钮后,初始化矩阵似乎仍然存在,并将新约束置于旧值之上。

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            HBox root = new HBox();
            VBox settings = new VBox();
            GridPane matrix = new GridPane();
            Button applyButton = new Button("Apply settings");
            TextField sizeMatrix = new TextField("size");
            TextField amountLivingCells = new TextField("living Cells");

            matrix.setMinHeight(400);
            matrix.setMinWidth(400);
            matrix.setMaxHeight(400);
            matrix.setMaxWidth(400);

            final int initialSize = 12;
            final int initialAmountBlackCells = 30;

            NumberBinding size = Bindings.min(matrix.widthProperty(),
                    matrix.heightProperty().subtract(50))
               .divide(20);

            //binding for size rounded down
            NumberBinding roundedSize = Bindings.createIntegerBinding(() -> size.intValue(), size);

            //initialize matrix
            setConstraints(matrix, initialSize);

            //fill out matrix with white Rectangles
            setBlankRectangles(matrix, roundedSize, initialSize);


            setRandomlyBlackRectangles(matrix, initialAmountBlackCells, initialSize);

            applyButton.setOnAction(new EventHandler<ActionEvent>() {
                @Override public void handle(ActionEvent e) {
                    int size = Integer.parseInt(sizeMatrix.getText());
                    int amountCells = Integer.parseInt(amountLivingCells.getText());

                    LogicMinimal.newMatrix(matrix, size);
                    LogicMinimal.fillMatrixWithDeadCells(matrix, size);
                    LogicMinimal.randomlySetLivingCells(matrix, amountCells, size);
                }
            });


            root.getChildren().addAll(settings, matrix);
            settings.getChildren().addAll(sizeMatrix, amountLivingCells, applyButton);
            settings.setSpacing(20);


            Scene scene = new Scene(root,800,800);
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    private void setRandomlyBlackRectangles(GridPane matrix, int amount, int sizeMatrix) {
        for(int i = 0; i < amount; i++)
            {
                int randomCol = ThreadLocalRandom.current().nextInt(1, sizeMatrix + 1);
                int randomRow = ThreadLocalRandom.current().nextInt(1, sizeMatrix + 1);

                for (Node node : matrix.getChildren()) 
                {
                    if (node instanceof Rectangle && 
                        GridPane.getColumnIndex(node) == randomCol && 
                        GridPane.getRowIndex(node) == randomRow) 
                    {
                        Rectangle cell = (Rectangle)node;
                        cell.setFill(Color.BLACK);
                    }
                }
            }
    }

    private void setBlankRectangles(GridPane matrix, NumberBinding roundedSize, int size) {
        for(int column = 0; column < size; column++)
        {
           for(int row = 0; row < size; row++)
              {
               Rectangle dead_cell = new Rectangle();
               dead_cell.setFill(Color.WHITE);
               dead_cell.widthProperty().bind(roundedSize);
               dead_cell.heightProperty().bind(roundedSize);

               GridPane.setColumnIndex(dead_cell, column);
               GridPane.setRowIndex(dead_cell, row);
               matrix.add(dead_cell, column, row);             
              }
         }
    }

    private void setConstraints(GridPane matrix, int size) {

        matrix.getRowConstraints().removeAll(matrix.getRowConstraints());
        matrix.getColumnConstraints().removeAll(matrix.getColumnConstraints());

        double cellWidth;
        double cellHeight;

        for(int i = 0; i < size; i++) 
        {
          ColumnConstraints colConst = new ColumnConstraints();
          cellWidth = 100.0 / size;
          colConst.setPercentWidth(cellWidth);    
          matrix.getColumnConstraints().add(colConst);

          RowConstraints rowConst = new RowConstraints();
          cellHeight = 100.0 / size;
          rowConst.setPercentHeight(cellHeight);
          matrix.getRowConstraints().add(rowConst);  
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

所以我看到的主要问题是这些行

LogicMinimal.newMatrix(matrix, size1);
LogicMinimal.fillMatrixWithDeadCells(matrix, size1);
LogicMinimal.randomlySetLivingCells(matrix, amountCells, size1);

这是因为您创建了一个新矩阵而没有删除旧矩阵,所以这导致它仍然显示在屏幕上。此外,您从未发布 LogicMinimal Class 的代码,因此我添加了必要的代码以使其 运行 正确

我还更改了以下两行,以便黑色方块出现在第 0 列和第 0 行中,您也可以随时恢复此更改

int randomCol = ThreadLocalRandom.current().nextInt(0, sizeMatrix + 1);//Change 1 to 0 to allow to be placed in col 0
int randomRow = ThreadLocalRandom.current().nextInt(0, sizeMatrix + 1);//Change 1 to 0 to allow to be placed in row 0

这是完全运行可用的class

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) {
        try {
            HBox root = new HBox();

            TextField sizeMatrix = new TextField();
            sizeMatrix.setPromptText("Size");

            TextField amountLivingCells = new TextField();
            amountLivingCells.setPromptText("living Cells");

            Button applyButton = new Button("Apply settings");
            applyButton.setOnAction(e -> {
                //Remove Old matrix
                GridPane oldMatrix = null;
                for (Node child : root.getChildren()) {
                    if(child instanceof GridPane) {
                        oldMatrix = (GridPane) child;
                        break;
                    }
                }
                root.getChildren().remove(oldMatrix);

                int size = Integer.parseInt(sizeMatrix.getText());
                int amountCells = Integer.parseInt(amountLivingCells.getText());

                //Build and Add new Matrix
                GridPane newMatrix = buildNewMatrix(size, amountCells);
                root.getChildren().add(newMatrix);

                //No longer needed
                //LogicMinimal.newMatrix(matrix, size1);
                //LogicMinimal.fillMatrixWithDeadCells(matrix, size1);
                //LogicMinimal.randomlySetLivingCells(matrix, amountCells, size1);
            });

            VBox settings = new VBox();
            settings.getChildren().addAll(sizeMatrix, amountLivingCells, applyButton);
            settings.setSpacing(20);

            GridPane matrix = buildNewMatrix(12, 30);

            root.getChildren().addAll(settings, matrix);


            Scene scene = new Scene(root,800,800);
            //scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());

            primaryStage.setScene(scene);
            primaryStage.show();

            applyButton.requestFocus();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    private GridPane buildNewMatrix(int initialSize, int initialAmountBlackCells){
        GridPane newMatrix = new GridPane();
        newMatrix.setMinHeight(400);
        newMatrix.setMinWidth(400);
        newMatrix.setMaxHeight(400);
        newMatrix.setMaxWidth(400);

        NumberBinding size = Bindings.min(newMatrix.widthProperty(),
                newMatrix.heightProperty().subtract(50))
                .divide(20);

        //binding for size rounded down
        NumberBinding roundedSize = Bindings.createIntegerBinding(size::intValue, size);

        //initialize newMatrix
        setConstraints(newMatrix, initialSize);

        //fill out newMatrix with white Rectangles
        setBlankRectangles(newMatrix, roundedSize, initialSize);

        setRandomlyBlackRectangles(newMatrix, initialAmountBlackCells, initialSize);

        return newMatrix;
    }

    private void setRandomlyBlackRectangles(GridPane matrix, int amount, int sizeMatrix) {
        for(int i = 0; i < amount; i++)
        {
            int randomCol = ThreadLocalRandom.current().nextInt(0, sizeMatrix + 1);//Change 1 to 0 to allow to be placed in col 0
            int randomRow = ThreadLocalRandom.current().nextInt(0, sizeMatrix + 1);//Change 1 to 0 to allow to be placed in row 0

            for (Node node : matrix.getChildren())
            {
                if (node instanceof Rectangle &&
                        GridPane.getColumnIndex(node) == randomCol &&
                        GridPane.getRowIndex(node) == randomRow)
                {
                    Rectangle cell = (Rectangle)node;
                    cell.setFill(Color.BLACK);
                }
            }
        }
    }

    private void setBlankRectangles(GridPane matrix, NumberBinding roundedSize, int size) {
        for(int column = 0; column < size; column++)
        {
            for(int row = 0; row < size; row++)
            {
                Rectangle dead_cell = new Rectangle();
                dead_cell.setFill(Color.WHITE);
                dead_cell.widthProperty().bind(roundedSize);
                dead_cell.heightProperty().bind(roundedSize);

                GridPane.setColumnIndex(dead_cell, column);
                GridPane.setRowIndex(dead_cell, row);
                matrix.add(dead_cell, column, row);
            }
        }
    }

    private void setConstraints(GridPane matrix, int size) {

        matrix.getRowConstraints().removeAll(matrix.getRowConstraints());
        matrix.getColumnConstraints().removeAll(matrix.getColumnConstraints());

        double cellWidth;
        double cellHeight;

        for(int i = 0; i < size; i++)
        {
            ColumnConstraints colConst = new ColumnConstraints();
            cellWidth = 100.0 / size;
            colConst.setPercentWidth(cellWidth);
            matrix.getColumnConstraints().add(colConst);

            RowConstraints rowConst = new RowConstraints();
            cellHeight = 100.0 / size;
            rowConst.setPercentHeight(cellHeight);
            matrix.getRowConstraints().add(rowConst);
        }
    }
}