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
的原因,因为它没有任何用途,因此从未被初始化。
我正在按照这个视频制作扫雷: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
的原因,因为它没有任何用途,因此从未被初始化。