I am writing a JavaFX program that makes a grid of random colors. When the window is resized the grid should adjust so it is as big as possible while still remaining square and leaving space on the bottom for the text.
Everything is working like it should but the problem I am having is that there are little gaps left in the GridPane when it is resized. The size of the gaps change slightly as the window is resized. Can someone please help me figure out how to eliminate these gaps? I am including the full code. It is not too long. Thank you.
import java.util.Random;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.stage.Stage;
/**
* Uses a 2D array to populate a grid of squares with random colors.
*/
public class Lab7 extends Application {
private Color[][] colorGrid = new Color[8][8];
private int redCellCount = 0;
/**
* Tells the program to start with the start() method since it is a JavaFX
* Application
*
* @param args
* arguments supplied to the program
*/
public static void main(String[] args) {
Application.launch(args);
}
/**
* Constructor for the class instantiates the 2D array of Color objects with
* random colors.
*/
public Lab7() {
// array of 12 awt colors not including white since it is used as the
// background color
Color[] colorList = { Color.BLACK, Color.BLUE, Color.CYAN, Color.DARKGREY, Color.GRAY, Color.GREEN,
Color.LIGHTGRAY, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.RED, Color.YELLOW };
// populate the 2D array of colors with random colors from the colorList
for (int i = 0; i < colorGrid.length; i++) {
for (int j = 0; j < colorGrid[i].length; j++) {
Random rand = new Random();
int colorCode = rand.nextInt(12);
if (colorCode == 10) {
redCellCount++;
}
colorGrid[i][j] = colorList[colorCode];
}
}
}
/*
* overridden method of the Application class. This is the entry point of
* the JavaFX application
*/
@Override
public void start(Stage stage) throws Exception {
// a GridPane that will hold the checkerboard of colors
GridPane checkerboardPane = new GridPane();
// a root pane for the layout
BorderPane parentPane = new BorderPane();
// create the scene and set the root node as the BorderPane and have the
// initial size be 400x400 pixels and set the background color to white
Scene scene = new Scene(parentPane, 400, 400);
parentPane.setStyle("-fx-background-color: " + toRGBCode(Color.WHITE));
// a Text object to display the number of red squares
Text redCellCountText = new Text("There are " + redCellCount + " red squares.");
// put the colorGrid in the center of the GridPane and the
// redCellCountText to the bottom
parentPane.setCenter(checkerboardPane);
parentPane.setBottom(redCellCountText);
// create 64 rectangles, fill them with the colors in the colorGrid and
// set a mouse click event handler
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
Rectangle rect = new Rectangle(scene.getWidth() / 8, scene.getWidth() / 8);
// bind the width property of the rectangle to 1/8 of the
// smaller of the scene width or height, leave 50 pixels at the
// bottom for the Text
rect.widthProperty()
.bind(Bindings
.when(scene.widthProperty().lessThanOrEqualTo(scene.heightProperty().subtract(50)))
.then(scene.widthProperty().divide(8))
.otherwise(scene.heightProperty().subtract(50).divide(8)));
// bind the width of the rectangle to its height so it will
// always be square
rect.heightProperty().bind(rect.widthProperty());
// set the color of the rectangle to correspond to the colorGrid
rect.setStyle("-fx-fill: " + toRGBCode(colorGrid[i][j]));
// set an event listener for the rectangle to handle when the
// user clicks on it
rect.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
// if the rectangle is not red
if (!((Rectangle) event.getSource()).getFill().equals(Color.RED)) {
// set its color to red
((Rectangle) event.getSource()).setFill(Color.RED);
// increment the redCellCount and update the text
redCellCount++;
redCellCountText.setText("There are " + redCellCount + " red squares.");
}
}
});
// add the rectangle to its respective square in the GridPane
checkerboardPane.add(rect, j, i);
}
}
// set the scene in the stage and set its title
stage.setScene(scene);
stage.setTitle("Lab7");
// show the stage to make it visible
stage.show();
}
/**
*
* @param color
* The JavaFX Color to convert
* @return the rgb code representing the JavaFX Color
*/
public static String toRGBCode(Color color) {
return String.format("#%02X%02X%02X", (int) (color.getRed() * 255), (int) (color.getGreen() * 255),
(int) (color.getBlue() * 255));
}
}
Well, these little gaps are coming from the calculation of the width of all Rectangles
, when you bind the value to the height of the Scene
.
Dirty solution is to add a -1 margin around the Rectangles using GridPane.setMargin(Node child, Insets value):
// add the rectangle to its respective square in the GridPane
checkerboardPane.add(rect, j, i);
GridPane.setMargin(rect, new Insets(-1, -1, -1, -1));