2016-11-14 3 views
0

Ich baue Sweeper nach diesem Video: https://www.youtube.com/watch?v=JwcyxuKko_MJavaFX wie behebe ich Strom()

Aber ich brauche ein MVC-Muster für diesen und ich bin fest mit einem NullPointer hier in der Zeile mit dem stream in View :

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

Hier ist die Field Klasse:

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

und die Variablen in 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]; 

Warum funktioniert es nicht? Ich versuche, eine Liste (mit allen Nachbarn eines Feldes) in den Stream zu geben und nach denen zu filtern, die Bomben enthalten, und dann diese Bomben zu zählen, damit ich diese Zahl auf dem aktuellen Feld anzeigen kann, damit der Spieler es weiß. Warum erkennt es nicht die Liste, die ich bestanden habe? Oder ist es der Filter, der verwirrt ist? Vielen Dank.

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

Haben Sie versucht, Ihren Code im Debug auszuführen? Überprüfen Sie zuerst, ob 'f' oder' field' null sind. – Spotted

+0

Können Sie erklären, wie Sie das richtig machen? Wenn ich debugge, bekomme ich nur die gleichen Fehler. Ich bin neu in diesem ... – dot

+0

Setzen Sie einen Haltepunkt in der Zeile, die diese Ausnahme auslöst. Bevor Sie diese Zeile ausführen, verwenden Sie den von Ihrer IDE bereitgestellten "Objektinspektor", um zu überprüfen, ob diese Variablen null sind oder nicht. – Spotted

Antwort

0

Ich denke, Sie haben ein Design-Problem in getSurrounding(). Im Moment müssen Sie ein Field als Argument übergeben, aber soweit ich verstehe, ist dieser Parameter non-sense. Wenn Sie die Umgebung eines Field greifen möchten, müssen Sie kein weiteres Field bereitstellen! Benutze einfach den aktuellen (diesen)!

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

Es heißt, Sie loszuwerden Attribut die Ansicht kann Field f, weil es jetzt nicht benutzt wird:

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 der Zeile, die Sie Problem im Moment werden kann verursacht geändert. Das war der Grund, warum es null war, weil es keinen Zweck hatte, deshalb wurde es nie initialisiert.

+0

Danke, das macht Sinn! Aber es funktioniert immer noch nicht und der Debugger sagt mir, dass er die lokale Variable "b" in "b.isBomb" nicht finden kann. Wie behebe ich das? Ich bin nicht sehr vertraut mit der Syntax von stream() und in all dem Beispiel sehe ich '(x -> x.variable)' oder '(d -> d.variable)' also habe ich es einfach kopiert, ohne es zu verstehen – dot

+0

@kris 'isBomb' ist von außerhalb von' Field' nicht zugänglich. Sie müssen einen Getter in 'Field' erstellen:' public boolean isBomb() {return isBomb; } 'und filtere dann entweder mit [method references] (https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html)' (Field :: isBomb) 'oder einem [lambda] (https: //docs.oracle.com/javase/tutorial/java/javaOO/lambdausexpressions.html) '(f -> f.isBomb())' – Spotted

+0

Das Ändern von 'getSurrounding()' wirft mir erneut den NullPointer. Es befindet sich in der letzten Zeile vor der Rückkehr 'Umgebung'. Befindet sich bei 'model.array'. Irgendwelche Ideen warum?'Umgebung' ist 0 und' Modell' ist null – dot

Verwandte Themen