JavaFX GridPane 单元格不会根据内容自动调整大小

标签 java user-interface javafx gridpane

我正在编写一个 JavaFX 程序,它可以生成随机颜色的网格。当调整窗口大小时,网格应该调整,使其尽可能大,同时仍然保持正方形并在底部为文本留出空间。

一切都按预期工作,但问题我遇到的是,调整大小时 GridPane 中留下的间隙很小。当窗口大小调整时,间隙的大小会略有变化。有人可以帮我弄清楚如何消除这些差距吗?我包括完整的代码。也不算太长。谢谢。

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

最佳答案

好吧,当您将值绑定(bind)到场景的高度时,这些小间隙来自所有矩形宽度的计算。

肮脏的解决方案是使用 GridPane.setMargin(Node child, Insets value) 在矩形周围添加 -1 边距:

// add the rectangle to its respective square in the GridPane
checkerboardPane.add(rect, j, i);
GridPane.setMargin(rect, new Insets(-1, -1, -1, -1));

关于JavaFX GridPane 单元格不会根据内容自动调整大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37557406/

相关文章:

JAVA:我的两个应用程序如何访问同一个文件?

javascript - 自定义数字输入

java - 不使用 CSS 样式化 JavaFX 组件

java - 如何在javafx中调用阶段的默认关闭操作?

JavaFX 模糊整个窗口

java - Smack 和 SASL 身份验证错误 - 没有已知的身份验证机制

Java 编译器选择了错误的重载

java - 您可以创建(Oracle JVM)java 堆的最小值是多少?

java - 当我按下 JButton 时,我的框架卡住了,为什么?图形用户界面

JavaFX:从选项卡 Controller 添加新选项卡