Как создать N ActionListener с циклом for? - PullRequest
0 голосов
/ 08 мая 2018

Я создал N (неизвестный размер) кнопок J с циклом for и поместил их в рамку. Я пытаюсь отобразить сообщение «Кнопка номер x», нажав на кнопку номер x. На втором цикле for, когда я пытаюсь создать N ActionListener, у меня возникает какая-то ошибка.

Ошибка

Локальная переменная I, определенная во вложенной области видимости, должна быть окончательной или фактически конечной

код

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 ]

0 голосов
/ 08 мая 2018

Вы могли бы сделать

JOptionPane.showMessageDialog(null, "Button number " + e.getActionCommand());
0 голосов
/ 08 мая 2018

Если анонимный класс создается внутри какого-либо метода, то все локальные переменные, определенные в методе, но вне тела анонимного класса, должны быть окончательными, если их необходимо использовать в анонимном классе.

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();
    }
}
0 голосов
/ 08 мая 2018

Вы не можете ссылаться на локальную переменную i внутри вашей реализации 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)
    );
} 
...