I'm trying to make a hangman game in javafx. So naturally, instead of making 26 individual buttons, I am trying to use a for loop to create each button. I am putting them into an ArrayList called alphabet and adding them to a flowPane. The trouble I am running into is when I try to set the action of each button to go to a function with the parameter of it's letter that checks to see if the letter has been used or if it is in the word.
All the instantiations:
ArrayList<Button> alphabet = new ArrayList<Button>();
FlowPane keyboard = new FlowPane();
letterGuess function (currently empty)
public void letterGuess(char letter) {
}
The code in my launch() function:
char letter;
for(int i=0 ; i<26 ; i++) {
letter = (char) (i+65);
alphabet.add(new Button("" + letter));
keyboard.getChildren().add(alphabet.get(i));
alphabet.get(i).setOnAction(e -> letterGuess(letter));
}
I expect the code to run through without an error and successfully pass letter to letterGuess() for each button. The error I get is at letter in alphabet.get(i).setOnAction(e -> letterGuess(letter)); The error says: Local variable letter defined in an enclosing scope must be final or effectively final
The issue is that you're declaring letter
outside the loop and thus trying to change it's value inside the loop. This means the lambda can't use it since it isn't a final or "effectively" final.
You can solve this by declaring the char
as new within the loop.
Here is another way you could write the loop which will work fine:
for (int i = 0; i < 26; i++) {
char letter = (char) (i + 65);
Button button = new Button(String.valueOf(letter));
button.setOnAction(event -> letterGuess(letter));
alphabet.add(button);
}
You could also declare letter
as final
within the loop, but it is not necessary in this case. Because letter
is only assigned a value once in the loop, it is effectively final
and the lamba knows it.