【问题标题】:How to align my rectangles in Java FX GridPane from my Main.java file?如何在我的 Main.java 文件中对齐 Java FX GridPane 中的矩形?
【发布时间】:2018-10-16 23:29:48
【问题描述】:

我正在尝试制作 Java 数独游戏。我无法对齐我的数独输入矩形。由于输入板底部的按钮,它们被移开。如何在我的Main.java 中对齐像我的expected.jpg 这样的矩形。我只想通过Main.java 文件制作我的ButtonsInput Rectangles。如果无法通过Main.java 进行对齐,请告诉我。谢谢

expected.jpg:

what_i_get.jpg:

Main.java:

package application;

import java.util.*;
import javafx.scene.shape.Rectangle;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.stage.Stage;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;

public class Main extends Application {
    int[][] original_map;
    StackPane[][] screen_buttons = new StackPane[10][10];

    @Override
    public void start(Stage primaryStage) {
        try {
            BorderPane root = new BorderPane();
            Scene scene = new Scene(root,600,700);
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }

        GridPane root = new GridPane();
        root.setPadding(new Insets(10));
        root.setHgap(10);
        root.setVgap(10);
        Scene scene = new Scene(root, 700, 700);
        primaryStage.setScene(scene);

    // USING SUDOKU.java to build the Sudoku Game
        Sudoku map = new Sudoku();
    // STORING the sudoku game in the 2x2 array
        this.original_map = map.make_game();

        for (int y=0;y<9;y++) {
            for (int x=0;x<9;x++) {
                screen_buttons[y][x] = new StackPane();
                Rectangle rec = new Rectangle(30,30);
                rec.setFill(javafx.scene.paint.Color.WHITE);
                rec.setStyle("-fx-arc-height: 10; -fx-arc-width: 10;");
                Label label = new Label(Integer.toString(this.original_map[y][x]));
                screen_buttons[y][x].getChildren().addAll(rec, label);
                root.add(screen_buttons[y][x], x, y);
            }
        }

        Button[] function_buttons = new Button[4];
        String[] function_id = {"Hint", "Clear", "Pause", "Check"};
        int pos = 0;
        for (Button b : function_buttons) {
            if (function_id[pos] == "Hint") {
                b = new Button(function_id[pos]);
                root.add(b, 1, pos+10);
            } else if (function_id[pos] == "Clear"){
                b = new Button(function_id[pos]);
                root.add(b, 1, pos+10);
            } else if (function_id[pos] == "Pause"){
                b = new Button(function_id[pos]);
                root.add(b, 1, pos+10);
            } else {
                b = new Button(function_id[pos]);
                root.add(b, 6, 11);
            }
            b.setStyle("-fx-pref-width: 100px; -fx-pref-height: 50px;");
            pos++;
        }

        Button[] click_buttons = new Button[9];
        pos = 1;
        for (int y=10;y<=12;y++) {
            for (int x=2;x<=4;x++) {
                click_buttons[pos-1] = new Button(Integer.toString(pos));
                root.add(click_buttons[pos-1], x, y);
                click_buttons[pos-1].setStyle("-fx-pref-width: 50px; -fx-pref-height: 50px;");
                pos++;
            }
        }
    }

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

【问题讨论】:

  • 首先,只有 9 x 9 的网格,为什么 screen_buttons 是一个 10 x 10 的数组?
  • @Jai 是我的错。假设写 9x9
  • 我在您的代码中没有看到任何 ColumnConstraintsRowConstraints。没有它们,GridPane 将根据可用空间自动调整列和行的大小。
  • 另外,如果您发布一个minimal reproducible example 将非常有帮助,以便我们编译、测试和改进代码。
  • @Zephyr 如何在Main.java 中添加ColumnConstraintsRowConstraints

标签: java javafx fxml


【解决方案1】:

更好地控制布局的常用策略是将其细分为更小、更易于管理的容器,每个容器都有自己的布局管理器。
在这种情况下,首先按照Jai 的建议将游戏及其控件分成两个容器:

public class Main extends Application {

    StackPane[][] screen_buttons = new StackPane[9][9];

    @Override
    public void start(Stage primaryStage) {

       //container for game
       BorderPane root = new BorderPane();

        GridPane grid = new GridPane();
        grid.setPadding(new Insets(10));
        grid.setHgap(10);
        grid.setVgap(10);

        for (int y=0;y<screen_buttons.length;y++) {
            for (int x=0;x<screen_buttons[y].length;x++) {
                screen_buttons[y][x] = new StackPane();
                Rectangle rec = new Rectangle(30,30);
                rec.setFill(javafx.scene.paint.Color.WHITE);
                rec.setStyle("-fx-arc-height: 10; -fx-arc-width: 10;");
                Label label = new Label("0");
                screen_buttons[y][x].getChildren().addAll(rec, label);
                grid.add(screen_buttons[y][x], x, y);
            }
        }

        //container for controls
        GridPane controls = new GridPane();

        Button[] function_buttons = new Button[4];
        String[] function_id = {"Hint", "Clear", "Pause", "Check"};
        int pos = 0;
        for (Button b : function_buttons) {
            if (function_id[pos] == "Hint") {
                b = new Button(function_id[pos]);
                controls.add(b, 1, pos+10);
            } else if (function_id[pos] == "Clear"){
                b = new Button(function_id[pos]);
                controls.add(b, 1, pos+10);
            } else if (function_id[pos] == "Pause"){
                b = new Button(function_id[pos]);
                controls.add(b, 1, pos+10);
            } else {
                b = new Button(function_id[pos]);
                controls.add(b, 6, 11);
            }
            b.setStyle("-fx-pref-width: 100px; -fx-pref-height: 50px;");
            pos++;
        }

        Button[] click_buttons = new Button[9];
        pos = 1;
        for (int y=10;y<=12;y++) {
            for (int x=2;x<=4;x++) {
                click_buttons[pos-1] = new Button(Integer.toString(pos));
                controls.add(click_buttons[pos-1], x, y);
                click_buttons[pos-1].setStyle("-fx-pref-width: 50px; -fx-pref-height: 50px;");
                pos++;
            }
        }

        root.setCenter(grid);
        root.setBottom(controls);
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

【讨论】:

  • 感谢您将其表达为实际示例(:
  • 谢谢,有帮助
【解决方案2】:

这里有几个问题(主要的和次要的)。

首先,screen_buttons 被声明为StackPane[10][10],这可能会在以后给您带来问题。

其次,我不知道你为什么要创建两个根节点和两个场景。它会起作用,但完全没有必要。

第三,您的GridPane 用作显示网格和控制按钮的公共根。下面的所有按钮都会影响顶部网格的列宽。您需要将这两者分开。您可以使用包含两个 GridPane 子节点的 BorderPane - 一个用于显示,另一个用于控制。

最后,执行Label label = new Label(Integer.toString(this.original_map[y][x])) 将使您的网格显示静态 值。虽然这对于预先生成值的网格来说看起来很棒,但当玩家在网格上放置一个数字时,这可能是一个问题。当然,您可以手动在用户执行操作时设置相应网格的文本,但这会使此处保留 2 个数组变得多余。

【讨论】:

  • 我尝试了你的第三个方法,但我无法正确对齐第二个 GirdPane 元素。
  • 谢谢,第三次帮助
猜你喜欢
  • 2016-05-14
  • 2013-12-21
  • 2019-12-29
  • 2014-09-13
  • 2016-04-22
  • 1970-01-01
  • 2019-01-08
  • 2014-11-09
  • 2012-09-21
相关资源
最近更新 更多