简体   繁体   中英

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

My task is to create an UI with a navigation tab on the left and a gridpane on the right (Scroll down for ui). First of all, I initialized the grid by adding Row- and Columnconstraints to it. It works completely fine after first starting the program.

It looks like:

在此处输入图片说明

After pressing the apply button with updated values, it seems that the initialized matrix is still there, with putting the new Constraints on top of the older values.

在此处输入图片说明

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);
    }
}

So the main problem I saw were these lines

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

This is because you create a new matrix and never remove the old so this caused it to still be displayed on the screen. Also you never posted the code for the LogicMinimal Class so I have added the necessary code to make it run properly

I have also changed the below 2 lines so that the black squares would appear in column and row 0 as well feel free to revert this change

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

This is the fully runnable 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);
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM