Полагаю, m
и n
объявлены как поля в окружающем классе (иначе ActionListener не сможет получить к ним доступ, то есть будет ошибка компилятора).
Метод actionPerformed вызывается, когдадействие нажимается.В это время циклы for завершили выполнение, оставив максимальное число столбца и строки в полях m
и n
.Иными словами, все слушатели действий обращаются к одним и тем же m
и n
, но все они должны видеть разные значения.
Это уже намекает на решение: каждому ActionListener нужны свои собственные переменные m
и n
.В коде:
final int col = m;
final int row = n;
but[m][n].addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e){
Column = col;
Row = row;
enablenumbers();
disablecolumns();
disablerows();
choose.setText("Now Choose The Nummber You Want To Put In This Square");
}
}
);
Обратите внимание, что переменные объявляются во внутреннем цикле for;они существуют только для одной итерации.Поскольку они являются окончательными, они видны анонимному внутреннему классу (под капотом значения этих конечных переменных будут скопированы в поля анонимного класса (доказательства этого утверждения приведены в приложении к этому ответу)
В качестве альтернативы, вы можете взять явный маршрут и использовать внутренний класс:
class MyActionListener implements ActionListener {
final int col;
final int row;
// constructor goes here
// impl of actionPerformed goes here, using col and row instead of m and n
}
, который вы бы прикрепили, используя
for (m = 0; m < width; m++){
for (n = 0; n < width; n++){
but[m][n].addActionListener(new MyActionListener(m,n));
}
}
Приложение: Реализация вложенного доступа к переменнымвнутренними классами
Для каждой конечной локальной переменной, объявленной во внешней области, к которой обращается внутренний класс, компилятор автоматически создает дополнительное поле во внутреннем классе для хранения его значения и вносит изменения в конструктор, чтобы назначитьполе из нового параметра конструктора. Это можно проверить, выполнив следующий код:
public class Test {
public static void main(final String[] args) throws Exception {
System.out.println(new Object() {
@Override
public String toString() {
for (Field f : getClass().getDeclaredFields()) {
System.out.println(f.getName());
}
System.out.println(getClass().getDeclaredConstructors()[0].toString());
return "" + args.length;
}
});
}
}
, который печатает:
val$args
Test$1(java.lang.String[])
0