Loop de Botões

Estou fazendo um programa que gera um loop de botões, e estou setando o uma ação padrão para estes botões, porém não consigo passar o parâmetro do map dentro do actionPerfomed.

     actionBut(e,variaveis.get("but"+i)); 

O erro é: local variables referenced from an inner class must be final or effectively final
Tem alguma maneira de arrumar isso?

package Telas;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import vistosofficial.VistosOfficial;


 public class Principal extends javax.swing.JFrame {
       VistosOfficial conex = new VistosOfficial();
       Color verd = new Color(51,255,0);
       Color azul = new Color(51,204,255);
       JButton but;

List<Integer> numeros = new ArrayList<Integer>();
Map<String, JButton> variaveis = new HashMap<String, JButton>();



public Principal() {
    initComponents();        
    botao(null);
}





public void botao(JButton btn){
    try{
    
    
    conex.executaSQL("select num from alunos where id_alunos between 2 and 45;");
    conex.rs.first();
    int x = 230;
    int y = 30;
    int x1 = 230;
    int cont =1;
    
    
    do{
    if(cont<=5){
        x=x+100;
        y=y;
        cont++;
    }else{
       y=y+30;
       cont=1;
       x=230;
    }
    int i=0;
    i++;
    but = new javax.swing.JButton();
    variaveis.put("but"+i, but);
    variaveis.get("but"+i).setText(String.valueOf(conex.rs.getInt("num")));
    variaveis.get("but"+i).setBackground(azul);
    variaveis.get("but"+i).setFont(new java.awt.Font("Arial Black", 1, 11));
    variaveis.get("but"+i).addActionListener(new java.awt.event.ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            //ESTÁ DANDO ERRO NA LINHA A SEGUIR
            actionBut(e,variaveis.get("but"+i));
       
        }
    });
    
    jPanel1.add(variaveis.get("but"+i));
    
    but.setBounds(x, y, 60, 20);
   
    
    
    }while(conex.rs.next());
    
    }catch(Exception ex){
        JOptionPane.showMessageDialog(null,"Erro ao criar botões: "+ ex.getMessage());
    }
}

   private void actionBut(java.awt.event.ActionEvent evt, JComponent comp){
 if(comp.getBackground()==azul){
     comp.setBackground(verd);
 }else{
     comp.setBackground(azul);
 }
}





@SuppressWarnings("unchecked")

public void run() {
            new Principal().setVisible(true);
        }
    });
}

// Variables declaration - do not modify                     
private javax.swing.JButton jButton1;
private javax.swing.JPanel jPanel1;
private javax.swing.JSeparator jSeparator1;
// End of variables declaration                   
}

Tens de declara o mapa com final

final Map<String, JButton> variaveis = new HashMap<String, JButton>();
1 curtida

Não funcionou isso.
Eu adicionei um ArrayList de JButtons para completar o Map e ao passar o parametro no ActionListener não deu mais problemas, porém a ação está sendo direcionada somente a um botão, de maneira que qualquer botão que eu clique só muda a cor do background do ultimo que foi criado.

Estás sempre a colocar i = 0 depois incrementar, o que quer dizer que no teu Map vais ter sempre só um “but1”.

A inicialização do i deve ser fora do do…while.

1 curtida

na verdade estava dentro do do - while , eu já arrumei usando um ArrayList ao invés do map, mas obrigado