Java 为什么网格窗格中的节点位置会影响网格的布局?

Java 为什么网格窗格中的节点位置会影响网格的布局?,java,javafx,gridpane,Java,Javafx,Gridpane,我正在尝试使用JavaFX中的GridPane重新创建“蛇”游戏。我的代码似乎运行正常,除了这个特定的错误,在这个错误中,每当我使用键将绿色节点(标题为head)向黄色节点(标题为food)移动时,网格的行或列似乎缩短了一个单位,导致网格以某种方式崩溃。有没有办法阻止GridPane调整大小?下面是我的代码: package snake; import java.util.ArrayList; import java.util.Random; import javafx.application

我正在尝试使用JavaFX中的GridPane重新创建“蛇”游戏。我的代码似乎运行正常,除了这个特定的错误,在这个错误中,每当我使用键将绿色节点(标题为head)向黄色节点(标题为food)移动时,网格的行或列似乎缩短了一个单位,导致网格以某种方式崩溃。有没有办法阻止GridPane调整大小?下面是我的代码:

package snake;

import java.util.ArrayList;
import java.util.Random;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.TilePane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Modality;
import javafx.stage.Stage;

public class snakemain extends Application {
    Random random = new Random();
    int posX = random.nextInt(21), posY = random.nextInt(21), foodposX = random.nextInt(24), foodposY = random.nextInt(24);

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

    public void start(Stage stage) {
        //Creates Scene and stage setting + gridpane
        stage.setTitle("Snake by Yeldor");
        GridPane gridpane = new GridPane();
        Random random = new Random();
        Scene scene = new Scene(gridpane, 500, 500);
        scene.setFill(Color.WHITE);
        gridpane.setGridLinesVisible(true);
        gridpane.setHgap(20);
        gridpane.setVgap(20);
        //creates head of snake, Arraylist of snakes body parts, and food consumable for snake
        ArrayList<Rectangle> snakeBody = new ArrayList<Rectangle>();
        Rectangle head = new Rectangle(20,20,Color.GREEN.brighter().brighter());
        //invisible block to manage grid
        Rectangle food = new Rectangle(20,20, Color.YELLOW.brighter().brighter());
        //adds rectangles to grippane
        gridpane.add(head, posX, posY);
        gridpane.add(food, foodposX, foodposY);
        //makes food non mangaged by the gridpane
        scene.setOnKeyPressed(e -> 
        {
            String s = e.getCode().toString();
        try {

            switch(s) {
            case "W":   gridpane.getChildren().remove(head);
                        gridpane.add(head, posX, --posY);
                    break;
            case "A":   gridpane.getChildren().remove(head);
                        gridpane.add(head, --posX, posY);
                    break;
            case "S":   gridpane.getChildren().remove(head);
                        gridpane.add(head, posX, ++posY);
                    break;
            case "D":   gridpane.getChildren().remove(head);
                        gridpane.add(head, ++posX, posY);
                    break;
            }


            if (posX == 24 || posY == 24 || posX == -1 || posY == -1) {
                missionFailed();
                stage.close();
            }

        }

        catch(IllegalArgumentException error) {
            missionFailed();
            stage.close();
        }

        });

        stage.setScene(scene);
        stage.show();

    }

    void missionFailed() {
        Stage failedPopup = new Stage();
        failedPopup.setTitle("You Died!");
        failedPopup.initModality(Modality.APPLICATION_MODAL);
        Button OK = new Button("OK");
        Group group = new Group();
        Scene miniScene = new Scene(group, 150, 100);
        group.getChildren().add(OK);
        failedPopup.setScene(miniScene);
        failedPopup.show();
        OK.setOnMouseClicked(q -> {
            failedPopup.close();
        });
    }

}
包装蛇;
导入java.util.ArrayList;
导入java.util.Random;
导入javafx.application.application;
导入javafx.scene.Group;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.input.KeyCode;
导入javafx.scene.layout.GridPane;
导入javafx.scene.layout.TilePane;
导入javafx.scene.paint.Color;
导入javafx.scene.shape.Rectangle;
导入javafx.stage.model;
导入javafx.stage.stage;
公共类snakemain扩展应用程序{
随机=新随机();
int posX=random.nextInt(21),posY=random.nextInt(21),foodposX=random.nextInt(24),foodposY=random.nextInt(24);
公共静态void main(字符串…参数){
发射(args);
}
公众假期开始(阶段){
//创建场景和舞台设置+网格窗格
舞台剧名(“耶尔多的蛇”);
GridPane GridPane=新建GridPane();
随机=新随机();
场景=新场景(网格窗格,500500);
场景。设置填充(颜色。白色);
setGridLinesVisible(true);
gridpane.setHgap(20);
网格窗格。setVgap(20);
//创建蛇头、蛇身体部位列表和蛇的食物消耗品
ArrayList snakeBody=新的ArrayList();
矩形头=新矩形(20,20,Color.GREEN.brighter().brighter());
//管理网格的不可见块
矩形食物=新矩形(20,20,颜色.黄色.明亮().明亮());
//将矩形添加到grippane
添加(head、posX、posY);
gridpane.add(食物,foodposX,foodposY);
//使食物不被烤盘弄坏
场景。按下设置键(e->
{
字符串s=e.getCode().toString();
试一试{
开关{
案例“W”:gridpane.getChildren().remove(head);
gridpane.add(head,posX,--posY);
打破
案例“A”:gridpane.getChildren().remove(head);
添加(head,--posX,posY);
打破
案例“S”:gridpane.getChildren().remove(head);
添加(head,posX,++posY);
打破
案例“D”:gridpane.getChildren().remove(head);
添加(head,++posX,posY);
打破
}
如果(posX==24 | | posY==24 | | posX==1 | | posY==1){
任务失败();
stage.close();
}
}
捕获(IllegalArgumentException错误){
任务失败();
stage.close();
}
});
舞台场景;
stage.show();
}
无效任务失败(){
阶段失败弹出=新阶段();
failedPopup.setTitle(“你死了!”);
failedPopup.InitModal(模态.应用程序\模态);
按钮OK=新按钮(“OK”);
组=新组();
场景迷你场景=新场景(组,150100);
group.getChildren().add(确定);
失败弹出。设置场景(迷你场景);
failedPopup.show();
好的。SetonMouseClacked(q->{
失败的弹出窗口。关闭();
});
}
}

使用
hgap
vgap
不会修改列大小,而是修改列之间的间距。例如,如果将
矩形
水平放置在彼此相邻的位置(行索引相同,列索引相差1),则两个节点之间的距离为
vgap
;正好有两列已填充且具有宽度!=0现在将
矩形
s移动到同一单元格中,只移动一列宽度!=0导致意外结果

相反,您应该限制行/列的大小:

// gridpane.setHgap(20);
// gridpane.setVgap(20);

int rows = 500 / 20;
int columns = 500 / 20;

RowConstraints rConstraints = new RowConstraints(20);
ColumnConstraints cConstraints = new ColumnConstraints(20);

for (int i = 0; i < columns; i++) {
    gridpane.getColumnConstraints().add(cConstraints);
}
for (int i = 0; i < rows; i++) {
    gridpane.getRowConstraints().add(rConstraints);
}
//gridpane.setHgap(20);
//网格窗格。setVgap(20);
int行=500/20;
int列=500/20;
RowConstraints rConstraints=新的RowConstraints(20);
ColumnConstraints=新的ColumnConstraints(20);
对于(int i=0;i
另一个对我有效的解决方案是用透明矩形填充整个区域,然后设置当前使用的矩形的颜色。

我不知道存在行和列约束类!非常感谢你!