JavaFX 如何修复 stream()

JavaFX how do I fix stream()

我正在按照这个视频制作扫雷:https://www.youtube.com/watch?v=JwcyxuKko_M

但是我为此需要一个 MVC 模式,我在 View:

中的 stream 行中遇到了 NullPointer
public class View{

Model model;
Field f; //here's where I'm trying to access the List created in Field class
Stage primarystage;
Text number = new Text();

public View(Model model, Stage primaryStage){

    this.model = model;
    this.primarystage = primaryStage;

    Pane root = new Pane();
    root.setPrefSize(model.WIDTH, model.HEIGHT);

    //iterate through rows and columns to fill board with random bombs
    for (int y = 0; y < model.Y_FIELDS; y++) {
        for (int x = 0; x < model.X_FIELDS; x++) {
            Field field = new Field(x, y, Math.random() < 0.2);
            model.array[x][y] = field;
            root.getChildren().add(field);

        }
    }

    for (int y = 0; y < model.Y_FIELDS; y++) {
        for (int x = 0; x < model.X_FIELDS; x++) {
            Field field = model.array[x][y];

    //trying to access the method getSurrounding from class Field with f
            long bombs = f.getSurrounding(field).stream().filter(b -> b.isBomb).count(); //number of bombs

            if (bombs > 0)
                field.bomb.setText(String.valueOf(bombs));
        }
    }
    Scene scene = new Scene(root, model.getWidth(), model.getHeight());
    getStage().setScene(scene);
}

这是 Field class:

import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;

import java.util.ArrayList;
import java.util.List;

public class Field extends StackPane{

//information for each field: x coordinate, y coordinate, is it a bomb or not
int x;
int y;
boolean isBomb;         //determines whether or not the field is a bomb
int bombsNum = 0;       //counts how many bombs are surrounding the field
Model model;

Rectangle board = new Rectangle(model.FIELD_SIZE - 2, model.FIELD_SIZE - 2);
Text bomb = new Text();

public Field(int x, int y, boolean isBomb){

    this.x = x;
    this.y = y;
    this.isBomb = isBomb;

    board.setFill(Color.LAVENDER);
    board.setStroke(Color.BLACK);
    bomb.setText(isBomb ? "X" : "");

    getChildren().addAll(board,bomb);

    setTranslateX(x * model.FIELD_SIZE);
    setTranslateY(y * model.FIELD_SIZE);
}

public List<Field> getSurrounding(Field field){

    //looks at all the fields surrounding the current field
    List<Field> surrounding = new ArrayList<>();

    int[] coordinates = new int[]{
            -1,-1,  //top left field
            -1, 0,  //left field
            -1, 1,  //bottom left field
             0,-1,  //top middle field
             0, 1,  //bottom middle field
             1,-1,  //top right field
             1, 0,  //right field
             1, 1   //bottom right field
    };

    for (int i = 0; i < coordinates.length; i++) {
        int columnX = coordinates[i];  //considers the x coordinate of a surrounding field
        int rowY = coordinates[++i];   //considers the y coordinate of a surrounding field

        int newX = field.x + columnX;  //sets the x coordinate of a surrounding field
        int newY = field.y + rowY;     //sets the y coordinate of a surrounding field

        if (newX >= 0 && newX < model.X_FIELDS                  //make sure it's not out of bounds
                && newY >= 0 && newY < model.Y_FIELDS) {
            surrounding.add(model.array[newX][newY]);
        }
    }

    return surrounding;
 }
}

以及Model中的变量:

public static final int FIELD_SIZE = 40;
public static final int WIDTH = 800;
public static final int HEIGHT = 600;

//sets number of fields in x and y axis
public static final int X_FIELDS = WIDTH / FIELD_SIZE;
public static final int Y_FIELDS = HEIGHT / FIELD_SIZE;

public Field[][] array = new Field[X_FIELDS][Y_FIELDS];

为什么它不起作用?我试图将一个列表(包含一个字段的所有邻居)传递到流中并过滤包含炸弹的列表,然后计算这些炸弹,以便我可以在当前字段上显示该数字,以便玩家知道。为什么它不识别我通过的列表?还是过滤器混淆了?谢谢。

Exception in Application start method
Exception in thread "main" java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication5(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
at View.<init>(View.java:46)
at Main.start(Main.java:10)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication12(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait5(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null3(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater4(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null8(WinApplication.java:191)

我认为您在 getSurrounding() 中存在设计问题。目前你需要传递一个 Field 作为参数,但据我所知,这个参数是 无意义的 。当你想抓取 Field 的周围环境时,你不需要提供另一个 Field !只需使用当前的 (this) !

public List<Field> getSurrounding() {
    //looks at all the fields surrounding the current field
    List<Field> surrounding = new ArrayList<>();

    int[] coordinates = new int[]{
        -1,-1,  //top left field
        -1, 0,  //left field
        -1, 1,  //bottom left field
         0,-1,  //top middle field
         0, 1,  //bottom middle field
         1,-1,  //top right field
         1, 0,  //right field
         1, 1   //bottom right field
    };

    for (int i = 0; i < coordinates.length; i++) {
        int columnX = coordinates[i];  //considers the x coordinate of a surrounding field
        int rowY = coordinates[++i];   //considers the y coordinate of a surrounding field

        int newX = this.x + columnX;  //sets the x coordinate of a surrounding field
        int newY = this.y + rowY;     //sets the y coordinate of a surrounding field

        if (newX >= 0 && newX < model.X_FIELDS                  
            && newY >= 0 && newY < model.Y_FIELDS) {
            surrounding.add(model.array[newX][newY]);
        }
    }

    return surrounding;
}

因此目前导致您出现问题的行可以更改为:

long bombs = field.getSurrounding().stream().filter(b -> b.isBomb).count();

这意味着您可以摆脱视图属性Field f,因为它现在未被使用。这就是为什么它是 null 的原因,因为它没有任何用途,因此从未被初始化。