Java For循环-此时变量-JButton的2D数组

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循环中遇到了一个大问题,我正在尝试为一系列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