问题
I'm trying to make a java Sudoku Game. I cannot align my Sudoku input rectangles. They are being shifted away because of the buttons at the bottom of the input board. How can I align the rectangles like my expected.jpg
in my Main.java
. I want to make my Buttons
and Input Rectangles
through the Main.java
file only. If it is not possible to make the alignment though Main.java
, please let me know. Thanks
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);
}
}
回答1:
A common strategy to gain better control over layout, is to sub-divide it into smaller, simpler to manage containers, each having its own layout manager.
In this case, start by separating the game and it's controls into two containers as proposed by 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:
There are several problems (major and minor ones) here.
Firstly, screen_buttons
is declared as StackPane[10][10]
, which can potentially give you problem later.
Secondly, I have no idea why you created two root nodes and two scenes. It would work, but totally unnecessary.
Thirdly, your GridPane
is used as the common root for the display grid and the control buttons. All the buttons below is affecting the column widths at the grid on top. You need to separate these two. You could use a BorderPane
containing two GridPane
child nodes - one for the display and another for control.
Lastly, doing Label label = new Label(Integer.toString(this.original_map[y][x]))
is going to make your grid display static values. While this looks great for grids pre-generated with values, this can be a problem when the player places a number on the grid. Of course, you could manually set the text of the corresponding grid when the user does an action, but this would make it redundant to keep 2 arrays here.
来源:https://stackoverflow.com/questions/52845315/how-to-align-my-rectangles-in-java-fx-gridpane-from-my-main-java-file