0

Im trying to make lists of rectangles in matrix like manner, I would want them to scale depending on amount of rectangles in row to always fit to the fixed size of window. End of row is little cut or couple of them are outside of border, depending on amount of rectangles.

public class Main extends Application {

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

    @Override
    public void start(Stage stage) {
        final int size = 80;
        stage.setWidth(1040);
        stage.setHeight(920);
        final double cellDimension = (stage.getWidth() / size) - 1;
        stage.setScene(new Scene(render(20, size, cellDimension), Color.WHITE));
        stage.show();
    }

    public static Region render(int generations, int size, double cellDimension) {
        VBox results = new VBox(0);
        Random random = new Random();
        for (int y = 0; y < generations; y++) {
            HBox hBox = new HBox(0);
            hBox.getChildren().addAll(IntStream.range(0, size).
                    mapToObj(idx -> random.nextInt(2)).map(item -> createAppropriateRectangle(item == 1, cellDimension)).
                    collect(Collectors.toList()));
            results.getChildren().add(hBox);
        }
        results.setSnapToPixel(true);
        return results;
    }

    private static Rectangle createAppropriateRectangle(boolean state, double cellDimension) {
        Rectangle rectangle = new Rectangle(cellDimension, cellDimension);
        rectangle.setStroke(Color.GRAY);
        if (state) {
            rectangle.setFill(Color.WHITE);
        }
        return rectangle;
    }
}

What am I doing wrong ? If something is unclear please let me know, thanks :) for list of 90 values, up is original, bottom shows how much was outside of border

EDIT: Made mwe using @DaveB stripped example

Waysker
  • 11
  • 3
  • Please post [mre] – c0der Aug 01 '21 at 14:06
  • Are you accounting for padding and gaps between rows and columns? – DaveB Aug 01 '21 at 16:02
  • It might not be not exactly what you want but is a bit similar, so perhaps you could learn or use something from it, see this [example of resizable swatches in a color chooser](https://gist.github.com/jewelsea/2030464). – jewelsea Aug 04 '21 at 23:08
  • Do want scaling to preserve the ratio of the two sides, similar to [what can be done when fitting an ImageView](https://openjfx.io/javadoc/16/javafx.graphics/javafx/scene/image/ImageView.html#preserveRatioProperty)? Are the rectangles, all, in fact, squares and the square dimensions should be maintained under scaling, e.g. the ratios preserved? – jewelsea Aug 04 '21 at 23:44
  • This question is quite unclear to me. What do mean by "scale"? Do you mean you want to add more fixed-size rectangles as the screen gets bigger and fewer when it gets smaller? Or should a fixed number of rectangles be displayed and each rectangle enlarged or shrunk depending on screen size? Should the number or size of rectangles change as the user resizes the screen? What about other UI elements, should they also scale or only the rectangles? Images and a better description would possibly help, but likely the question will be closed because the problem is not well described. – jewelsea Aug 05 '21 at 21:20

2 Answers2

0

Building a MRE would probably have shown you the answer fairly quickly. It looks like using a GridPane was just an attempt to make the rectangles fit, but GridPane potentially adds complexity that may obscure the answer. So I went with a VBox holding a bunch of HBoxes. That handles the relative positioning of the elements without any fuss.

You didn't include the Generator class, meaning your code was un-runnable, so I've stripped it down to just the mechanics of putting some random black and white squares on the screen, and dumped everything else:

public class Squares extends Application {

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

    @Override
    public void start(Stage stage) {
        final int size = 80;
        stage.setWidth(1040);
        stage.setHeight(920);
        final double cellDimension = (stage.getWidth() / size) - 1;
        stage.setScene(new Scene(render(20, size, cellDimension), Color.WHITE));
        stage.show();
    }

    public static Region render(int generations, int size, double cellDimension) {
        VBox results = new VBox(0);
        Random random = new Random();
        for (int y = 0; y < generations; y++) {
            HBox hBox = new HBox(0);
            hBox.getChildren().addAll(IntStream.range(0, size).mapToObj(idx -> random.nextInt(2)).map(item -> createAppropriateRectangle(item == 1, cellDimension)).collect(Collectors.toList()));
            results.getChildren().add(hBox);
        }
        return results;
    }

    private static Rectangle createAppropriateRectangle(boolean state, double cellDimension) {
        Rectangle rectangle = new Rectangle(cellDimension, cellDimension);
        rectangle.setStroke(Color.GRAY);
        if (state) {
            rectangle.setFill(Color.WHITE);
        }
        return rectangle;
    }
}

It looks like you need to allow 1 extra pixel per rectangle to make the math work properly. Also, it seems to work only when the stage width divides nicely by the number of rectangles per row - there's probably some mechanics of partial pixels that comes into play here. You could probably find a rounding policy that would work when the row size is not an even divisor of the stage width.

DaveB
  • 1,836
  • 1
  • 15
  • 13
  • I tried this with my code, didn't help, even for numbers that divide nicely. I used your code to edit my question and make mwe, hope you don't mind. This code still behaves same and cuts rectangles, I also added `Region.setSnapToPixel(false)`. – Waysker Aug 03 '21 at 16:16
  • All I can say is that the code I posted, as it was posted, worked perfectly and fit the Rectangles exactly onto the Stage on my system. – DaveB Aug 03 '21 at 20:04
-1

You can bind it to stage or parent width, height property. Binding is one of the most powerful concepts of JavaFX.

java programming
  • 125
  • 2
  • 11