我见过其他具有类似问题的线程,但是在这些线程中,解决方案是创建一个带有值副本的最终变量,以使该变量有效地成为最终变量。但是,我的问题源于一个事实,即产生错误的变量是保存类实例的2D数组。
以下是发生错误的Controller类的代码:
package Controller;
import Model.Die;
import View.GameWindow;
import View.HelpWindow;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Controller {
private GameWindow view;
private static int pos[] = new int[2];
private Die diceLayout[][];
private String createdWord;
public Controller(){
view = new GameWindow();
addHelpListener();
addSubmitListener();
diceLayout = view.getDice();
}
private void submitWord(String word){
boolean valid = checkValidWord(word);
if(valid){
System.out.println("The word ‘"+word+"‘ is valid.");
}else{System.out.println("The word ‘"+word+"‘ is not valid.");}
}
private boolean checkValidWord(String word){
boolean validSpell = validWordDic(word);
boolean connected = checkWordConnected(word);
if(validSpell&&connected){
return true;
}else{
return false;
}
}
private static boolean validWordDic(String word){
word=word.toLowerCase();
try {
BufferedReader in = new BufferedReader(new FileReader("C:\\Users\\sambe\\Desktop\\IPT\\BoggleGame\\res\\dictionary.txt"));
String str;
while ((str = in.readLine()) != null) {
if (str.indexOf(word) != -1) {
return true;
}
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
public boolean checkWordConnected(String word){
word = word.toLowerCase();
String letters[] = word.split("");
for(int i = 0; i<4; i++){
for(int j = 0; j<4; j++){
if(letters[0]==diceLayout[i][j].getText()){
pos[0]=i;
pos[1]=j;
}
}
}
return true;
}
private void addHelpListener(){
view.getHelpButton().addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
HelpWindow helpWin = new HelpWindow();
System.out.println("done");
}
});
}
private void addSubmitListener(){
view.getSubmitButton().addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("done");
if(view.getSubmitField().getText()!=null){
submitWord(view.getSubmitField().getText());
}else{
submitWord(createdWord);
createdWord="";
}
view.getSubmitField().setText("");
}
});
}
private void addDiceListeners(){
for(int i = 0; i<4; i++){
for(int j = 0; j<4; j++){
diceLayout[i][j].addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
diceLayout[i][j].setClicked(true); //Error Occurs here
}
});
}
}
}
}
如果有人对如何解决此问题有任何建议,将不胜感激。谢谢!
答案 0 :(得分:3)
这与数组无关,与循环计数器有关。由于i
和j
并不是有效的最终形式(它们通过循环递增),因此不能在匿名类中使用它们。
diceLayout[i][j].setClicked(true);
^
error here (and if you fixed that, it would appear at j)
您可以将Die
提取到局部变量中,因此只能在侦听器外部访问i
和j
:
private void addDiceListeners()
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
Die die = diceLayout[i][j];
die.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
die.setClicked(true);
}
});
}
}
}
答案 1 :(得分:1)
这里:
diceLayout[i][j].setClicked(true); //Error Occurs here
您的问题是i和j。这些是封闭方法中的 local 变量。 当然,这些是 loop 计数器,因此您不能将它们定为最终计数器。
这应该做:
for(int i = 0; i<4; i++) {
for(int j = 0; j<4; j++) {
final int finalRow = i;
final int finalColumn = j;
然后使用刚创建的两个最终副本代替i和j。或者,按照其他答案的建议进行操作,然后获取要使用的实际Die
对象(作为最终对象)。