Java For循环-此时变量-JButton的2D数组
我在下面的for循环中遇到了一个大问题,我正在尝试为一系列JButton创建操作侦听器,每个JButton都必须为“Column”和“Row”分配不同的值,但是,对于所有按钮,“Column”和“Row”只会成为for循环中可能的最高值,就像for循环中的m上升到7一样,“Column”将等于所有按钮的7,它不构成犯罪。换句话说,我希望第一个按钮'but[0][0]'使'Column'等于0,但我也希望'but[1][0]'使'Column'等于1,依此类推。任何帮助都将不胜感激 按钮的用途是更改程序中其他地方声明的“列”和“行”的值,因此每个按钮都需要使“列”和“行”相等Java For循环-此时变量-JButton的2D数组,java,multidimensional-array,for-loop,2d,jbutton,Java,Multidimensional Array,For Loop,2d,Jbutton,我在下面的for循环中遇到了一个大问题,我正在尝试为一系列JButton创建操作侦听器,每个JButton都必须为“Column”和“Row”分配不同的值,但是,对于所有按钮,“Column”和“Row”只会成为for循环中可能的最高值,就像for循环中的m上升到7一样,“Column”将等于所有按钮的7,它不构成犯罪。换句话说,我希望第一个按钮'but[0][0]'使'Column'等于0,但我也希望'but[1][0]'使'Column'等于1,依此类推。任何帮助都将不胜感激 按钮的用途是更
for (m = 0; m < width; m++){
for (n = 0; n < width; n++){
but[m][n].addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e){
Column = m;
Row = n;
enablenumbers();
disablecolumns();
disablerows();
choose.setText("Now Choose The Nummber You Want To Put In This Square");
}
}
);
}
}
for(m=0;m
我刚刚仔细查看了您的代码;你是如何编译的?您不能像这样访问匿名内部类中的非final字段(列,m,n
)。这个怎么样
for (int m = 0; m < width; m++)
{
for (int n = 0; n < width; n++)
{
final int innerM = m;
final int innerN = n;
but[m][n].addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
setColumnAndRow(innerM, innerN);
enablenumbers();
disablecolumns();
disablerows();
choose.setText("Now Choose The Nummber You Want To Put In This Square");
}
});
}
}
/*Sets the value of Column and Row when a button is clicked*/
private void setColumnAndRow(int m, int n)
{
Column = m;
Row = n;
}
for(int m=0;m
几点注意:
- 在变量名上-在Java中,变量名通常以小写字母和驼峰字母开头,因此
而不是行
和行
而不是列
,列
而不是myVariable
或myu variable
或变体myu variable
- 关于行与列的比较-Java(以及从C派生语法的大多数其他语言)具有基于0的二维数组,其中第一个索引选择行,第二个索引选择列。我不确定您的目的是什么,但您可能会发现其他人会因为您切换两个索引而感到困惑(即,我希望
而不是相反)arr[row][col]
- 很难说没有看到更多的代码,但看起来您在循环中设置了两个变量
列和行
,然后在循环外部使用它们。如果您只是在循环外处理这些变量,那么当您退出时,它们将始终设置为最大值(因为只有循环的最后一次迭代才会起作用)
您可能希望直接在actionPerformed
方法中使用m
和n
值,而不是等到循环执行后再使用。要么在ActionListener中定义列变量,要么在ActionListener外部定义行变量(否则最终将始终使用与循环中最后声明的值相同的值)我认为您需要创建自己的类,该类实现ActionListener
,并具有存储列和行值的成员变量。将构造函数中的列和行值提供给该类
如前所述,所有的ActionListener
对象都将从同一列和行中读取变量的值,因此所有的变量都将以分配给这些变量的最后一个值结束,我猜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));
}
}
其中打印:
val$args
Test$1(java.lang.String[])
0
谢谢你的回答,但我想我应该提到“列”和“行”在程序的其他地方声明,基本上每个按钮的目的是根据按下哪个按钮来改变它们的值。但是谢谢你的回答。(我将把这个添加到原始问题中)我现在明白了——我也意识到我以前的代码不会编译,你的代码也不会
val$args
Test$1(java.lang.String[])
0