Lambda 表达式在封闭范围 JavaFx 中定义的局部变量文本

Lambda Expression Local variable text defined in an enclosing scope JavaFx

我正在使用 JavaFX 创建一个扫雷游戏。我有一个 lambda 表达式,当我从按钮网格中按下一个按钮时(现在),它会将按钮的文本设置为二维数组中的位置。我收到错误 "Local variable text defined in an enclosing scope must be final or effectively final."

我知道我在 lambda 表达式中使用的变量无法完成,因为它们必须在表达式之外是最终的。但我不知道如何解决这个问题。

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

它在同一个错误中标记了 i、j 和文本。

gridSize 是我的扫雷网格的大小。 buttonGrid 是我放置在 gridPane 中的按钮网格。

我在 Whosebug 上看到了将这些变量设置为全局变量的解决方案,但是没有用。

只需将 text 的定义移动到循环内(这样您就可以在循环的每次迭代中定义一个新的、有效的最终变量)。您也可以用相同的方式定义一个 Button 变量,以避免引用 ij:

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