I am using JavaFX to create a minesweeper game. I have a lambda expression where (for now) when I press a button from the grid of buttons, it sets the text of the button to be the location in the 2D array. I am getting the error "Local variable text defined in an enclosing scope must be final or effectively final."
I understand that the variables I am using in the lambda expression cant be done because they have to be final outside the expression. but I cant figure out how to get around that.
static Stage stage;
Button[][] buttonGrid;
public void start(Stage primaryStage) throws Exception {
SetSettings.readSettings();
GridPane gridpane = new GridPane();
int gridSize = Minesweeper.gridSize;
buttonGrid = new Button[gridSize][gridSize];
for (int i = 0; i < gridSize; i++) {
for (int j = 0; j < gridSize; j++) {
buttonGrid[i][j] = new Button();
GridPane.setConstraints(buttonGrid[i][j], j, i);
}
}
String text = "";
for (int i = 0; i < gridSize; i++) {
for (int j = 0; j < gridSize; j++) {
text += i + "" + j;
buttonGrid[i][j].setOnAction(e -> {
buttonGrid[i][j].setText(text);
text = "";
});
gridpane.getChildren().add(buttonGrid[i][j]);
}
}
stage = primaryStage;
primaryStage.setOnCloseRequest(e -> {
e.consume();
ConfirmExit.display("Exit", "Are you sure you want to quit this game?");
});
primaryStage.setTitle("Minesweeper");
stage.getIcons().add(new Image("/Logo.jpg"));
Scene scene = new Scene(gridpane, 600, 500);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
It is flagging i, j, and text in the same error.
gridSize is the size of my grid for minesweeper. buttonGrid is the grid of buttons I am placing in the gridPane.
I saw a solution on stackoverflow to set these variables as global, but that did not work.
Just move the definition of text
inside the loop (so you define a new, effectively final, variable on each iteration of the loop). You can also define a Button
variable in the same way, to avoid referencing i
and j
:
for (int i = 0; i < gridSize; i++) {
for (int j = 0; j < gridSize; j++) {
String text = i + "" + j;
Button button = buttonGrid[i][j] ;
button.setOnAction(e -> {
button.setText(text);
});
gridpane.getChildren().add(buttonGrid[i][j]);
}
}