I'm trying to write a simple JavaFX application that contains a graphical representation of an NxM matrix (default 100 x 100). I would like to bind the matrix size to the Scene size, so when I resize the app window, the matrix follows it and keeps the aspect ratio. The binding works seamlessly for small matrices (for example 10x10), but when the matrix gets bigger (for example 50x50) and rectangles get smaller so they can fit my screen, the binding process becomes discontinuous. The matrix sometimes even gets bigger than window size (can't see all cells/rectangles) and matrix size seems like it's switching between integer values.

What I did is created a StackPane as a root Node inside the Scene and a GridPane as a child Node to the StackPane. I filled the GridPane with an NxM Rectangle matrix.

The code follows:

```java
public class GridPaneExample extends Application {

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

    @Override
    public void start(Stage primaryStage) throws Exception {
        int n = 100, m = 100; // matrix size
        double rectw = 5, recth = 5; // size of each rectangle
        StackPane root = new StackPane();
        Scene scene = new Scene(root, (m + 2) * rectw, (n + 2) * recth, Color.DARKOLIVEGREEN); // creating a scene with
                                                                                                // a frame around matrix
        primaryStage.setScene(scene);
        primaryStage.sizeToScene();

        GridPane gp = new GridPane();
        root.getChildren().add(gp);
        Rectangle[][] rects = new Rectangle[n][m];
        for (int i = 0; i < n; ++i)
            for (int j = 0; j < m; ++j) {
                rects[i][j] = new Rectangle();
                rects[i][j].setWidth(rectw);
                rects[i][j].setHeight(recth);
                rects[i][j].setFill(Color.ANTIQUEWHITE);
                rects[i][j].setStrokeType(StrokeType.INSIDE);
                rects[i][j].setStrokeWidth(0.2);
                rects[i][j].setStroke(Color.GREY);

                rects[i][j].widthProperty().bind(gp.widthProperty().divide(m));
                rects[i][j].heightProperty().bind(gp.heightProperty().divide(n));

                GridPane.setRowIndex(rects[i][j], i);
                GridPane.setColumnIndex(rects[i][j], j);
                gp.getChildren().add(rects[i][j]);
            }

        rects[0][0].setFill(Color.RED);
        rects[0][m - 1].setFill(Color.RED);
        rects[n - 1][0].setFill(Color.RED);
        rects[n - 1][m - 1].setFill(Color.RED);

        StackPane.setAlignment(gp, Pos.TOP_CENTER);
        gp.minHeightProperty().bind(scene.heightProperty().subtract(2 * recth));
        gp.minWidthProperty().bind(scene.widthProperty().subtract(2 * rectw));
        gp.maxHeightProperty().bind(scene.heightProperty().subtract(2 * recth));
        gp.maxWidthProperty().bind(scene.widthProperty().subtract(2 * rectw));
        root.setLayoutY(recth);

        primaryStage.show();
        primaryStage.setMinHeight(primaryStage.getHeight());
        primaryStage.setMinWidth(primaryStage.getWidth());

    }
}

```

Here are some screenshots of the program showing different sized matrices.

A 10 x 10 matrix app when started (rectangle size is 20x20):

<https://i.imgur.com/I2vMLSD.png>

A 10 x 10 matrix app when stretched:

<https://i.imgur.com/9rR3e0g.png>

A 100 x 100 matrix app when started (rectangle size is 5x5):

<https://i.imgur.com/1KCKg6W.png>

A 100 x 100 matrix app when stretched a bit, see how the matrix gets out of bounds:

<https://i.imgur.com/pG8DxXA.png>

So, is there a way to make this binding experience smooth and consistent, maybe by using something else other than Rectangles?

Edit: A weird thing happens. When I remove the rectangle binding lines from code and launch the app with 100x100 matrix, the matrix looks as it should. The program prints out the size of the GridPane and red rectangles. They are 500x500 and 5x5 respectively, as expected. However, when I include rectangle binding (as shown in the code), the matrix gets out of bounds, as in third photo attached, but the program still prints out the same dimensions of GridPane and rectangles.