使用数组添加 actionPerformed

Add actionPerformed with array

我正在编写 Tic-Tac-Toe 游戏。

我通过数组创建了按钮,但现在我尝试通过 for 循环向每个按钮添加 ActionListeneractionPerformed。当我尝试这样做时发生错误:

Local variable i defined in an enclosing scope must be final or effectively final

我不知道如何解决这个问题。 (第 35 行: System.out.println("You clicked the Button" + i + ", " + k);

import java.awt.FlowLayout;
import java.util.Random;
import java.awt.event.*;
import javax.swing.*;

public class TicTacToearray {
    
    static String players; 
    static JLabel gametext;
    static int round;
    static int maxWidth = 3;
    static int maxHeight = 3;
    static JButton[][] buttonfields = new JButton[maxWidth][maxHeight];
    
    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        }
        JFrame mainFrame = new JFrame("Tic-Tac-Toe");
        mainFrame.getContentPane().setLayout(new FlowLayout());
        for (int i = 0; i < maxWidth; i++) {
            for (int k = 0; k < maxHeight; k++) {
                buttonfields [i][k] = new JButton("  ");
                mainFrame.add(buttonfields[i][k], maxWidth * i + k);
                buttonfields[i][k].addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        System.out.println("You clicked the Button" + i + ", " + k);
                        System.out.println("Does that work:" + buttonfields[i][k]);
                    }
                });
            }
        }
        mainFrame.pack();
        mainFrame.setVisible(true);
        mainFrame.setResizable(true);
        mainFrame.setSize(180,150);
        mainFrame.setResizable(false);
        JLabel gametext = new JLabel();
        mainFrame.add(gametext);
        mainFrame.setLocationRelativeTo(null);
        Random rand = new Random();
        int beginnernr = rand.nextInt(2);
        if (beginnernr == 1) {
            players = "O";
            gametext.setText("It's " + players + " turn!");
        } if (beginnernr == 0) {
            players = "X";
            gametext.setText("It's " + players + " turn!");
        }
        if (round == 9) {
            gametext.setText("Game Over");
        }
    }
}

您尝试创建的'Anonymous' new ActionListener() {...}它可以用lambda代替)是它将在操作之后执行的东西按钮将完成。为了能够编译在 anonymous/lambda 中使用的值,它们需要是最终的以保证它们在运行时可以访问。

快速修复可以是这样的:

final int finalI = i;
final int finalK = k;
buttonfields[i][k].addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        System.out.println("You clicked the Button" + finalI + ", " + finalK);
        System.out.println("Does that work:" + buttonfields[finalI][finalK]);
    }
});

此外,使用 lambda 的代码可能如下所示:

final int finalI = i;
final int finalK = k;
buttonfields[i][k].addActionListener(e -> {
    System.out.println("You clicked the Button" + finalI + ", " + finalK);
    System.out.println("Does that work:" + buttonfields[finalI][finalK]);
});

更紧凑一些。