2016-11-14 40 views
0

我建立扫雷下面这个视频:https://www.youtube.com/watch?v=JwcyxuKko_M的JavaFX我怎么修复流()

但我需要这样的MVC模式,我套牢了NullPointer这里与streamView行:

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; 
} 
} 

而且在变量:

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) 
+0

您是否尝试在调试中运行代码?首先检查“f”或“field”是否为空。 – Spotted

+0

你能解释一下如何正确地做到这一点吗?当我点击调试时,我只会得到相同的错误。我是新手... – dot

+0

在引发此异常的行上放置一个断点。在执行此行之前,请使用IDE提供的“对象检查器”来检查这些变量是否为空。 – Spotted

回答

0

我觉得你的设计问题在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; 
} 

Thefore导致你目前的问题行可以改为:

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

这意味着你可以摆脱视图属性Field f,因为它现在是闲置。这就是为什么它是null,因为它没有任何目的,因此从未初始化。

+0

谢谢,这很有道理!但它仍然不工作,调试器告诉我他在'b.isBomb'中找不到局部变量'b'。我该如何解决?我不是很熟悉stream()的语法,在所有的例子中我看到'(x - > x.variable)'或'(d - > d.variable)',所以我只是复制它而不理解它 – dot

+0

无法从Field的外部访问@kris'isBomb'。你必须在'Field'中创建一个getter:'public boolean isBomb(){return isBomb; }'然后使用[方法引用](https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html)'(Field :: isBomb)'或者[lambda](https: (f - > f.isBomb())' – Spotted

+0

改变'getSurrounding()'会再次抛出我的NullPointer。它位于返回'surround'前的最后一行。位于'model.array'。任何想法为什么?'surround'为0,'model'为null – dot