有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何使用for循环创建ActionListener?

我已经用for循环创建了N个(未知大小)jbutton,并将它们放置在框架中。 我试图通过单击按钮编号x来显示消息“按钮编号x”。 在第二个for循环中,当我试图创建一个ActionListener时,出现了一些错误

错误

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

代码

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class program extends JFrame{
    final int N = 10;
    final int JUMPS = 210;
    private JButton[] buttons = new JButton[N];

    public program(){
        super("test");
        setLayout(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        for (int i = 0; i < N; i++) {
            buttons[i] = new JButton("" + i);
            buttons[i].setBounds((i % 4) * JUMPS, (i / 4) *JUMPS , 200, 200);
            add(buttons[i]);
        }

        for (int i = 0; i < N; i++) {
            buttons[i].addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    JOptionPane.showMessageDialog(null, "Button number " + i);
                }
            });
        } 

        pack();
        setVisible(true);
    }

    public static void main(String[] args) {
        program mainGUI = new program();
    }
}

你有解决这个错误的办法吗


共 (3) 个答案

  1. # 1 楼答案

    你可以

    JOptionPane.showMessageDialog(null, "Button number " + e.getActionCommand());
    
  2. # 2 楼答案

    如果匿名类是在任何方法中创建的,那么在该方法中定义但在匿名类主体之外的所有局部变量都应该是最终的,以防它们需要在匿名类中使用

    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    
    public class program extends JFrame{
        final int N = 10;
        final int JUMPS = 210;
        private JButton[] buttons = new JButton[N];
    
        public program(){
            super("test");
            setLayout(null);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            for (int i = 0; i < N; i++) {
                buttons[i] = new JButton("" + i);
                buttons[i].setBounds((i % 4) * JUMPS, (i / 4) *JUMPS , 200, 200);
                add(buttons[i]);
            }
    
            for (int i = 0; i < N; i++) {
            final int buttonNumber = i ;
                buttons[i].addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        JOptionPane.showMessageDialog(null, "Button number " + buttonNumber);
                    }
                });
            } 
    
            pack();
            setVisible(true);
        }
    
        public static void main(String[] args) {
            program mainGUI = new program();
        }
    }
    
  3. # 3 楼答案

    除非i是final(或实际上是final),否则不能在ActionListener实现中引用局部变量i。但你可以做一个最终的变量并引用它

    for (int i = 0; i < N; i++) {
        final int final_i = i;
        buttons[i].addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(null, "Button number " + final_i);
            }
        });
    } 
    

    在Java 8中,您可以更仔细地执行以下操作:

    for (int i = 0; i < N; i++) {
        final int final_i = i;
        buttons[i].addActionListener(e ->
           JOptionPane.showMessageDialog(null, "Button number " + final_i)
        );
    }