2016-11-14 67 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