操作 GridPane 中的行数和列数
Manipulating the number of rows and columns in GridPane
我在 MapTest class 中初始化了 rowSize(行数)和 colSize(列数)。我创建了 3 个方法:startStage1()、startStage2() 和 startStage3();每个都分配给一个按钮。每个方法都将 rowSize 和 colSize 分配给一个新的整数。
我希望能够在每次单击按钮时重新调整 GridPane 的大小,但这种方式行不通。
我可以做些什么不同的事情?
import javafx.application.Application;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class MapTest extends Application implements EventHandler<KeyEvent> {
static Stage theStage;
static Scene scene1, scene2;
// top box
HBox topBox = new HBox();
// bottom box
HBox bottomBox = new HBox();
// grid dimensions (I'm trying to manipulate these variables)
int rowSize;
int colSize;
int tileSize;
GridPane gridPane;
GridMapT gridMap;
@Override
public void start(Stage firstStage) throws Exception {
theStage = firstStage;
// scene 2 //////////////
Label label2 = new Label("scene 2: choose a stage");
Button stage1_btn = new Button("Room 5x5");
Button stage2_btn = new Button("Room 7x7");
Button stage3_btn = new Button("Room 10x10");
Button button5 = new Button("Exit");
stage1_btn.setOnAction(e -> {
startStage1();
});
stage2_btn.setOnAction(e -> {
startStage2();
});
stage3_btn.setOnAction(e -> {
startStage3();
});
button5.setOnAction(e -> System.exit(0));
// Layout1
VBox layout = new VBox(20);
layout.setAlignment(Pos.CENTER);
layout.getChildren().addAll(label2, stage1_btn, stage2_btn, stage3_btn, button5);
scene1 = new Scene(layout, 800, 600);
// Scene 3 ////////////////////
// top box
Label title = new Label("Map test");
topBox.getChildren().add(title);
// bottom box
Label instruction = new Label("");
bottomBox.getChildren().add(instruction);
// scene 3
BorderPane gameScreen = new BorderPane();
scene2 = new Scene(gameScreen);
// set up gridPane
gridPane = new GridPane();
gridMap = new GridMapT(rowSize, colSize);
for (int x = 0; x < rowSize; x++) {
for (int y = 0; y < colSize; y++) {
String grid = gridMap.getMap()[x][y];
// floor labels
if (grid == "floor") {
Label table = new Label("F");
table.setMinWidth(tileSize);
table.setMinHeight(tileSize);
gridPane.add(table, x, y);
}
// wall labels
if (grid == "wall") {
Label table = new Label("W");
table.setMinWidth(tileSize);
table.setMinHeight(tileSize);
gridPane.add(table, x, y);
}
}
}
////// ////////////////////////////////////////////////////////////////////////
// add a clickable reset and Debug Mode to bottom box
Button resetBtn = new Button();
resetBtn.setText("Quit game");
bottomBox.getChildren().add(resetBtn);
resetBtn.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<Event>() {
@Override
public void handle(Event event) {
try {
restart(firstStage);
} catch (Exception e) {
e.printStackTrace();
}
}
});
// keyboard input
scene2.setOnKeyPressed(this);
// setting up the whole borderPane
gameScreen.setTop(topBox);
gameScreen.setBottom(bottomBox);
gameScreen.setCenter(gridPane);
// set scene1 as start up screen
firstStage.setScene(scene1);
firstStage.show();
}
// restart method
public void restart(Stage stage) throws Exception {
topBox.getChildren().clear();
bottomBox.getChildren().clear();
gridPane.getChildren().clear();
gridMap = new GridMapT(rowSize, colSize);
start(stage);
}
///////////////////////////////////////////////////////////////////////////////////////
// stage setting methods
public void startStage1() {
rowSize = 21;
colSize = 21;
tileSize = 40;
theStage.setScene(scene2);
}
public void startStage2() {
rowSize = 29;
colSize = 29;
tileSize = 30;
theStage.setScene(scene2);
}
public void startStage3() {
rowSize = 41;
colSize = 41;
tileSize = 20;
theStage.setScene(scene2);
}
@Override
public void handle(KeyEvent event) {
// TODO Auto-generated method stub
}
public static void main(String[] args) {
launch(args);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// GridMap Class
public class GridMapT {
private String[][] map;
public GridMapT(int rowSize, int colSize) {
this.map = new String[rowSize][colSize];
// set up wall and fog
for (int i = 0; i < rowSize; i++) {
for (int j = 0; j < colSize; j++) {
if (i % 4 == 0 || j % 4 == 0) {
map[i][j] = "wall";
} else {
map[i][j] = "floor";
}
}
}
}
public String[][] getMap() {
return map;
}
}
}
我对您的代码进行了一些更改并使其正常运行。
首先 Application#start
方法 不应被系统以外的任何人调用 。它是您应用的入口点,手动调用它会破坏应用的生命周期。
其次,没有必要在 start
方法中创建 GridMapT
实例,因为您不知道它运行时应该有多少列和行。这就是为什么这里也没有必要将地图放入您的 GridPane
。
第三,您需要在需要更新地图时随时创建新的 GridMapT
实例或更改现有实例。因此,在您创建新地图或更新现有(添加或删除项目)后,您需要将其放入您的 GridPane
。创建地图和更新网格的两段代码似乎没问题,但是在错误的时间和错误的地方调用了它们。
最后 int
类型是 Java 中的 原始。更改任何 int
值只会影响它,您仍然需要重新创建 and/or 手动更新任何依赖于它的东西。这意味着您每次更改它们时都需要手动 create/update 映射新的 colSize
和 rowSize
值。如果您创建新地图,您需要手动将其传递给您的 GridPane
实例。
一般来说,您应用的逻辑应该如下所示:
- 创建舞台、场景、组件。
- 显示第一个场景
- 等待用户输入(点击、大小等)
- 更新第二个场景
- 显示第二个场景
- 等待用户输入(点击
Quit
)
- 关闭第二个场景
- 根据用户的操作重复3-7
这里还有一些事情可以做得更好,祝你好运,找到并改进它们:)
改进代码:
public class Test extends Application implements EventHandler<KeyEvent>{
static Stage theStage;
static Scene scene1, scene2;
// top box
HBox topBox = new HBox();
// bottom box
HBox bottomBox = new HBox();
// grid dimensions (I'm trying to manipulate these variables)
int rowSize;
int colSize;
int tileSize;
GridPane gridPane;
GridMapT gridMap;
@Override
public void start(Stage firstStage) throws Exception{
theStage = firstStage;
// scene 2 //////////////
Label label2 = new Label("scene 2: choose a stage");
Button stage1_btn = new Button("Room 5x5");
Button stage2_btn = new Button("Room 7x7");
Button stage3_btn = new Button("Room 10x10");
Button button5 = new Button("Exit");
stage1_btn.setOnAction(e -> {
startStage1();
});
stage2_btn.setOnAction(e -> {
startStage2();
});
stage3_btn.setOnAction(e -> {
startStage3();
});
button5.setOnAction(e -> System.exit(0));
// Layout1
VBox layout = new VBox(20);
layout.setAlignment(Pos.CENTER);
layout.getChildren().addAll(label2, stage1_btn, stage2_btn, stage3_btn, button5);
scene1 = new Scene(layout, 800, 600);
// Scene 3 ////////////////////
// top box
Label title = new Label("Map test");
topBox.getChildren().add(title);
// bottom box
Label instruction = new Label("");
bottomBox.getChildren().add(instruction);
// scene 3
BorderPane gameScreen = new BorderPane();
scene2 = new Scene(gameScreen);
// set up gridPane
gridPane = new GridPane();
////// ////////////////////////////////////////////////////////////////////////
// add a clickable reset and Debug Mode to bottom box
Button resetBtn = new Button();
resetBtn.setText("Quit game");
bottomBox.getChildren().add(resetBtn);
resetBtn.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<Event>(){
@Override
public void handle(Event event){
try {
//There's no need to call start method anymore.
//Think of the stage like it's your app's window
//and of a scene like it is window's content.
//restart(firstStage);
firstStage.setScene(scene1);
} catch (Exception e) {
e.printStackTrace();
}
}
});
// keyboard input
scene2.setOnKeyPressed(this);
// setting up the whole borderPane
gameScreen.setTop(topBox);
gameScreen.setBottom(bottomBox);
gameScreen.setCenter(gridPane);
// set scene1 as start up screen
firstStage.setScene(scene1);
firstStage.show();
}
//TODO pass rowSize and colSize here
private void createMap(){
gridMap = new GridMapT(rowSize, colSize);
}
//TODO pass gridMap
private void redrawMap(){
gridPane.getChildren().clear();
for (int x = 0; x < rowSize; x++) {
for (int y = 0; y < colSize; y++) {
String grid = gridMap.getMap()[x][y];
// floor labels
if (grid == "floor") {
Label table = new Label("F");
table.setMinWidth(tileSize);
table.setMinHeight(tileSize);
gridPane.add(table, x, y);
}
// wall labels
if (grid == "wall") {
Label table = new Label("W");
table.setMinWidth(tileSize);
table.setMinHeight(tileSize);
gridPane.add(table, x, y);
}
}
}
}
// restart method
public void restart(Stage stage) throws Exception{
topBox.getChildren().clear();
bottomBox.getChildren().clear();
gridPane.getChildren().clear();
gridMap = new GridMapT(rowSize, colSize);
start(stage);
}
///////////////////////////////////////////////////////////////////////////////////////
// stage setting methods
public void startStage1(){
rowSize = 21;
colSize = 21;
tileSize = 40;
createMap();
redrawMap();
theStage.setScene(scene2);
}
public void startStage2(){
rowSize = 29;
colSize = 29;
tileSize = 30;
createMap();
redrawMap();
theStage.setScene(scene2);
}
public void startStage3(){
rowSize = 41;
colSize = 41;
tileSize = 20;
createMap();
redrawMap();
theStage.setScene(scene2);
}
@Override
public void handle(KeyEvent event){
// TODO Auto-generated method stub
}
public static void main(String[] args){
launch(args);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// GridMap Class
public class GridMapT{
private String[][] map;
public GridMapT(int rowSize, int colSize){
this.map = new String[rowSize][colSize];
// set up wall and fog
for (int i = 0; i < rowSize; i++) {
for (int j = 0; j < colSize; j++) {
if (i % 4 == 0 || j % 4 == 0) {
map[i][j] = "wall";
} else {
map[i][j] = "floor";
}
}
}
}
public String[][] getMap(){
return map;
}
}
}
我在 MapTest class 中初始化了 rowSize(行数)和 colSize(列数)。我创建了 3 个方法:startStage1()、startStage2() 和 startStage3();每个都分配给一个按钮。每个方法都将 rowSize 和 colSize 分配给一个新的整数。
我希望能够在每次单击按钮时重新调整 GridPane 的大小,但这种方式行不通。 我可以做些什么不同的事情?
import javafx.application.Application;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class MapTest extends Application implements EventHandler<KeyEvent> {
static Stage theStage;
static Scene scene1, scene2;
// top box
HBox topBox = new HBox();
// bottom box
HBox bottomBox = new HBox();
// grid dimensions (I'm trying to manipulate these variables)
int rowSize;
int colSize;
int tileSize;
GridPane gridPane;
GridMapT gridMap;
@Override
public void start(Stage firstStage) throws Exception {
theStage = firstStage;
// scene 2 //////////////
Label label2 = new Label("scene 2: choose a stage");
Button stage1_btn = new Button("Room 5x5");
Button stage2_btn = new Button("Room 7x7");
Button stage3_btn = new Button("Room 10x10");
Button button5 = new Button("Exit");
stage1_btn.setOnAction(e -> {
startStage1();
});
stage2_btn.setOnAction(e -> {
startStage2();
});
stage3_btn.setOnAction(e -> {
startStage3();
});
button5.setOnAction(e -> System.exit(0));
// Layout1
VBox layout = new VBox(20);
layout.setAlignment(Pos.CENTER);
layout.getChildren().addAll(label2, stage1_btn, stage2_btn, stage3_btn, button5);
scene1 = new Scene(layout, 800, 600);
// Scene 3 ////////////////////
// top box
Label title = new Label("Map test");
topBox.getChildren().add(title);
// bottom box
Label instruction = new Label("");
bottomBox.getChildren().add(instruction);
// scene 3
BorderPane gameScreen = new BorderPane();
scene2 = new Scene(gameScreen);
// set up gridPane
gridPane = new GridPane();
gridMap = new GridMapT(rowSize, colSize);
for (int x = 0; x < rowSize; x++) {
for (int y = 0; y < colSize; y++) {
String grid = gridMap.getMap()[x][y];
// floor labels
if (grid == "floor") {
Label table = new Label("F");
table.setMinWidth(tileSize);
table.setMinHeight(tileSize);
gridPane.add(table, x, y);
}
// wall labels
if (grid == "wall") {
Label table = new Label("W");
table.setMinWidth(tileSize);
table.setMinHeight(tileSize);
gridPane.add(table, x, y);
}
}
}
////// ////////////////////////////////////////////////////////////////////////
// add a clickable reset and Debug Mode to bottom box
Button resetBtn = new Button();
resetBtn.setText("Quit game");
bottomBox.getChildren().add(resetBtn);
resetBtn.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<Event>() {
@Override
public void handle(Event event) {
try {
restart(firstStage);
} catch (Exception e) {
e.printStackTrace();
}
}
});
// keyboard input
scene2.setOnKeyPressed(this);
// setting up the whole borderPane
gameScreen.setTop(topBox);
gameScreen.setBottom(bottomBox);
gameScreen.setCenter(gridPane);
// set scene1 as start up screen
firstStage.setScene(scene1);
firstStage.show();
}
// restart method
public void restart(Stage stage) throws Exception {
topBox.getChildren().clear();
bottomBox.getChildren().clear();
gridPane.getChildren().clear();
gridMap = new GridMapT(rowSize, colSize);
start(stage);
}
///////////////////////////////////////////////////////////////////////////////////////
// stage setting methods
public void startStage1() {
rowSize = 21;
colSize = 21;
tileSize = 40;
theStage.setScene(scene2);
}
public void startStage2() {
rowSize = 29;
colSize = 29;
tileSize = 30;
theStage.setScene(scene2);
}
public void startStage3() {
rowSize = 41;
colSize = 41;
tileSize = 20;
theStage.setScene(scene2);
}
@Override
public void handle(KeyEvent event) {
// TODO Auto-generated method stub
}
public static void main(String[] args) {
launch(args);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// GridMap Class
public class GridMapT {
private String[][] map;
public GridMapT(int rowSize, int colSize) {
this.map = new String[rowSize][colSize];
// set up wall and fog
for (int i = 0; i < rowSize; i++) {
for (int j = 0; j < colSize; j++) {
if (i % 4 == 0 || j % 4 == 0) {
map[i][j] = "wall";
} else {
map[i][j] = "floor";
}
}
}
}
public String[][] getMap() {
return map;
}
}
}
我对您的代码进行了一些更改并使其正常运行。
首先 Application#start
方法 不应被系统以外的任何人调用 。它是您应用的入口点,手动调用它会破坏应用的生命周期。
其次,没有必要在 start
方法中创建 GridMapT
实例,因为您不知道它运行时应该有多少列和行。这就是为什么这里也没有必要将地图放入您的 GridPane
。
第三,您需要在需要更新地图时随时创建新的 GridMapT
实例或更改现有实例。因此,在您创建新地图或更新现有(添加或删除项目)后,您需要将其放入您的 GridPane
。创建地图和更新网格的两段代码似乎没问题,但是在错误的时间和错误的地方调用了它们。
最后 int
类型是 Java 中的 原始。更改任何 int
值只会影响它,您仍然需要重新创建 and/or 手动更新任何依赖于它的东西。这意味着您每次更改它们时都需要手动 create/update 映射新的 colSize
和 rowSize
值。如果您创建新地图,您需要手动将其传递给您的 GridPane
实例。
一般来说,您应用的逻辑应该如下所示:
- 创建舞台、场景、组件。
- 显示第一个场景
- 等待用户输入(点击、大小等)
- 更新第二个场景
- 显示第二个场景
- 等待用户输入(点击
Quit
) - 关闭第二个场景
- 根据用户的操作重复3-7
这里还有一些事情可以做得更好,祝你好运,找到并改进它们:)
改进代码:
public class Test extends Application implements EventHandler<KeyEvent>{
static Stage theStage;
static Scene scene1, scene2;
// top box
HBox topBox = new HBox();
// bottom box
HBox bottomBox = new HBox();
// grid dimensions (I'm trying to manipulate these variables)
int rowSize;
int colSize;
int tileSize;
GridPane gridPane;
GridMapT gridMap;
@Override
public void start(Stage firstStage) throws Exception{
theStage = firstStage;
// scene 2 //////////////
Label label2 = new Label("scene 2: choose a stage");
Button stage1_btn = new Button("Room 5x5");
Button stage2_btn = new Button("Room 7x7");
Button stage3_btn = new Button("Room 10x10");
Button button5 = new Button("Exit");
stage1_btn.setOnAction(e -> {
startStage1();
});
stage2_btn.setOnAction(e -> {
startStage2();
});
stage3_btn.setOnAction(e -> {
startStage3();
});
button5.setOnAction(e -> System.exit(0));
// Layout1
VBox layout = new VBox(20);
layout.setAlignment(Pos.CENTER);
layout.getChildren().addAll(label2, stage1_btn, stage2_btn, stage3_btn, button5);
scene1 = new Scene(layout, 800, 600);
// Scene 3 ////////////////////
// top box
Label title = new Label("Map test");
topBox.getChildren().add(title);
// bottom box
Label instruction = new Label("");
bottomBox.getChildren().add(instruction);
// scene 3
BorderPane gameScreen = new BorderPane();
scene2 = new Scene(gameScreen);
// set up gridPane
gridPane = new GridPane();
////// ////////////////////////////////////////////////////////////////////////
// add a clickable reset and Debug Mode to bottom box
Button resetBtn = new Button();
resetBtn.setText("Quit game");
bottomBox.getChildren().add(resetBtn);
resetBtn.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<Event>(){
@Override
public void handle(Event event){
try {
//There's no need to call start method anymore.
//Think of the stage like it's your app's window
//and of a scene like it is window's content.
//restart(firstStage);
firstStage.setScene(scene1);
} catch (Exception e) {
e.printStackTrace();
}
}
});
// keyboard input
scene2.setOnKeyPressed(this);
// setting up the whole borderPane
gameScreen.setTop(topBox);
gameScreen.setBottom(bottomBox);
gameScreen.setCenter(gridPane);
// set scene1 as start up screen
firstStage.setScene(scene1);
firstStage.show();
}
//TODO pass rowSize and colSize here
private void createMap(){
gridMap = new GridMapT(rowSize, colSize);
}
//TODO pass gridMap
private void redrawMap(){
gridPane.getChildren().clear();
for (int x = 0; x < rowSize; x++) {
for (int y = 0; y < colSize; y++) {
String grid = gridMap.getMap()[x][y];
// floor labels
if (grid == "floor") {
Label table = new Label("F");
table.setMinWidth(tileSize);
table.setMinHeight(tileSize);
gridPane.add(table, x, y);
}
// wall labels
if (grid == "wall") {
Label table = new Label("W");
table.setMinWidth(tileSize);
table.setMinHeight(tileSize);
gridPane.add(table, x, y);
}
}
}
}
// restart method
public void restart(Stage stage) throws Exception{
topBox.getChildren().clear();
bottomBox.getChildren().clear();
gridPane.getChildren().clear();
gridMap = new GridMapT(rowSize, colSize);
start(stage);
}
///////////////////////////////////////////////////////////////////////////////////////
// stage setting methods
public void startStage1(){
rowSize = 21;
colSize = 21;
tileSize = 40;
createMap();
redrawMap();
theStage.setScene(scene2);
}
public void startStage2(){
rowSize = 29;
colSize = 29;
tileSize = 30;
createMap();
redrawMap();
theStage.setScene(scene2);
}
public void startStage3(){
rowSize = 41;
colSize = 41;
tileSize = 20;
createMap();
redrawMap();
theStage.setScene(scene2);
}
@Override
public void handle(KeyEvent event){
// TODO Auto-generated method stub
}
public static void main(String[] args){
launch(args);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// GridMap Class
public class GridMapT{
private String[][] map;
public GridMapT(int rowSize, int colSize){
this.map = new String[rowSize][colSize];
// set up wall and fog
for (int i = 0; i < rowSize; i++) {
for (int j = 0; j < colSize; j++) {
if (i % 4 == 0 || j % 4 == 0) {
map[i][j] = "wall";
} else {
map[i][j] = "floor";
}
}
}
}
public String[][] getMap(){
return map;
}
}
}