【问题标题】:JavaFX how do I fix stream()JavaFX如何修复流()
【发布时间】:2016-11-14 08:02:22
【问题描述】:

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

但是我需要一个 MVC 模式来解决这个问题,我在这里遇到了 NullPointerView 中的 stream 一致:

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 类:

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$launchApplication$155(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$launchApplication1$162(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(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$null$148(WinApplication.java:191)

【问题讨论】:

  • 您是否尝试在调试中运行您的代码?首先检查ffield 是否为空。
  • 你能解释一下如何正确地做到这一点吗?当我点击调试时,我只会得到相同的错误。我是新手……
  • 在抛出此异常的行上放置一个断点。在执行此行之前,请使用 IDE 提供的“对象检查器”检查这些变量是否为空。
  • 谢谢!发现f 为空。现在怎么办?它还说找不到局部变量b.isBomb
  • f 到底是什么?您可以使用显示f 的编码以及您如何在代码的其他地方使用它来编辑您的帖子吗?

标签: javafx filter java-stream minesweeper


【解决方案1】:

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

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 的原因,因为它没有目的,因此从未初始化。

【讨论】:

  • 谢谢,有道理!但它仍然无法正常工作,调试器告诉我他在b.isBomb 中找不到局部变量b。我该如何解决?我对 stream() 的语法不是很熟悉,在所有示例中我看到 (x -&gt; x.variable)(d -&gt; d.variable) 所以我只是复制它而不理解它
  • @kris isBomb 无法从 Field 的外部访问。您必须在 Field: public boolean isBomb() { return isBomb; } 中创建一个吸气剂,然后使用 method references (Field::isBomb)lambda (f -&gt; f.isBomb()) 进行过滤
  • 更改 getSurrounding() 再次向我抛出 NullPointer。它位于返回surrounding 之前的最后一行。位于model.array。任何想法为什么? surroundings 为 0,model 为空
  • @kris 因为modelnull。你需要在Field构造函数中初始化它...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-07
  • 1970-01-01
  • 1970-01-01
  • 2019-12-03
  • 2020-01-22
  • 1970-01-01
相关资源
最近更新 更多