[Resolvido] Não consigo criar JButtons em runtime com diferentes Actions

Bom dia!
Eu tenho vindo a ter esta duvida já a algum tempo… Tentei procurar pelo forum mas não encontrei nada que me ajudasse, por isso decidi criar este tópico.

O cenário é o seguinte, eu tenho dentro do meu programa uma parte em que apresenta a planta de determinada fábrica. A cada zona da fábrica eu chamo-lhe de local, como por exemplo ‘Modelação’.

A cada local da fábrica estão associadas várias portas de rede. Por exemplo o local ‘Modelação’, tem as portas ‘A01’, ‘B02’, ‘C03’;

O que estou a tentar fazer é, que sempre que programa apresente o local, apareça também ao lado da imagem do local (planta do local), as portas associadas (em forma de botões).
E que o utilizador ao carregar em tal botão, apresente as informações dessa porta.

Quanto a isso está tudo a funcionar, ou seja, sempre que o utilizador quer ver um local, aparece as portas associadas.
O que não está a funcionar é, que quando o utilizador carrega no botão para ver as suas informações, o programa só apresenta as informações da ultima porta.

Não sei como explicar melhor, mas os botões são apresentados assim:

Ao carregar em ‘A01’, devia de aparecer as informações da ‘A01’, e não na ‘C03’, como acontece…
Se for a ver a qualquer outro local, e carregar em qualquer botão, irá sempre aparecer as informações da ultima porta criada.

Deixo aqui o código que utilizo:

Tenho uma classe Botao:

[code]public class Botao
{
private int SizeX = 0, SizeY = 0, LocationX = 0, LocationY = 0;
private String info, nomePorta;
private JButton tb1;
private ActionListener acao;
private Connection ligacao;
private Statement expressao;
private ResultSet resultado;

public Botao(int sizeX, int sizeY, int locationX, int locationY)
{
    SizeX = sizeX;
    SizeY = sizeY;
    LocationX = locationX;
    LocationY = locationY;
}

public JButton criarBotao(ActionListener action, String PainelPorta, String PortaPorta, int i)
{
    tb1 = new JButton((PainelPorta + PortaPorta));
    tb1.setName((PainelPorta + PortaPorta));
    tb1.setSize(SizeX, SizeY);
    tb1.setMargin(new Insets(2, 2, 2, 2));
    tb1.setLocation(LocationX, LocationY + (i * 25));
    tb1.setFont(new Font("tahoma", 0, 11));
    tb1.addActionListener(action);
    return tb1;
}

public ActionListener criarAction(String PainelPorta, String PortaPorta)
{
    try
    {
        ligacao = DriverManager.getConnection(GlobalSyskECh.getSQL_BD(), GlobalSyskECh.getSQL_User(), GlobalSyskECh.getSQL_Pass());
        expressao = ligacao.createStatement();
        String query = "SELECT * FROM Portas WHERE NumPorta like '" + PortaPorta + "' and Painel like '" + PainelPorta + "'";
        String msg = "";
        resultado = expressao.executeQuery(query);
        resultado.first();
        if (!resultado.getString(8).equals("Porta não usada."))
        {
            msg = "Porta " + resultado.getString(2) + 

resultado.getString(1) + “.\n” + "Licação ao Switch " +
resultado.getString(6) + " porta " + resultado.getString(7) + “.\n” +
"Nesta porta está ligado um " + resultado.getString(3) + “.\n” + "Ultimas obs.: " + resultado.getString(8);
} else
{
msg = "Porta " + resultado.getString(2) + resultado.getString(1) + “.\n” + “Porta não utilizada.”;
}
info = msg;
nomePorta = PainelPorta + PortaPorta;
acao = new ActionListener()
{

            public void actionPerformed(ActionEvent e)
            {
                JOptionPane.showMessageDialog(null, info, "Porta " + nomePorta, JOptionPane.INFORMATION_MESSAGE);
            }
        };
        ligacao.close();
    } catch (SQLException ex)
    {
        JOptionPane.showMessageDialog(null, "Botao.java [1]\nErro de 

SQL. \nErro: " + ex.getMessage(), “ERRO!”, JOptionPane.ERROR_MESSAGE);
}
return acao;
}
}[/code]

E o código que utilizo para imprimir os botões com as suas actions:

[code]
ArrayList ArrayBotoes = new ArrayList();
ArrayList ArrayAction = new ArrayList();

painelPortasAssociadas.removeAll();
int i = 0;

sql = “Select Painel, NumPorta FROM Portas WHERE LocalDaPorta like '” + ComboLocais.getSelectedItem().toString() + “’”;
resultado = expressao.executeQuery(sql);
resultado.beforeFirst();

while (resultado.next())
{
ArrayAction.add(b.criarAction(resultado.getString(1), resultado.getString(2)));
}
resultado.beforeFirst();

while (resultado.next())
{
ArrayBotoes.add(b.criarBotao(ArrayAction.get(i), resultado.getString(1), resultado.getString(2), i));
i++;
}

for (i = 0; i < ArrayBotoes.size(); i++)
   {
     painelPortasAssociadas.add(ArrayBotoes.get(i));
    }

    painelPortasAssociadas.repaint();[/code]

Peço que me ajudem, que preciso mesmo disto e não sei mais o que tentar, e isto é para um trabalho de fim de curso.
Muito obrigado pela atenção.

Já resolvi!

O que fiz foi criar uma nova classe que estende a AbstractAction.

[code]public class MinhaAcao extends AbstractAction
{

private String PainelPorta, PortaPorta;
private Connection ligacao;
private Statement expressao;
private ResultSet resultado;

public MinhaAcao(String Painel, String Porta)
{
    super("Minha Acção");
    putValue(SHORT_DESCRIPTION, "Informações sobre a porta.");
    PainelPorta = Painel;
    PortaPorta = Porta;
}

public void actionPerformed(ActionEvent e)
{
    try
    {
        ligacao = DriverManager.getConnection(GlobalSyskECh.getSQL_BD(), GlobalSyskECh.getSQL_User(), GlobalSyskECh.getSQL_Pass());
        expressao = ligacao.createStatement();
        String query = "SELECT * FROM Portas WHERE NumPorta like '" + PortaPorta + "' and Painel like '" + PainelPorta + "'";
        String msg = "";
        resultado = expressao.executeQuery(query);
        resultado.first();
        if (!resultado.getString(8).equals("Porta não usada."))
        {
            msg = "Porta " + resultado.getString(2) + resultado.getString(1) + ".\n" + "Licação ao Switch " + resultado.getString(6) + " porta " + resultado.getString(7) + ".\n" + "Nesta porta está ligado um " + resultado.getString(3) + ".\n" + "Ultimas obs.: " + resultado.getString(8);
        } else
        {
            msg = "Porta " + resultado.getString(2) + resultado.getString(1) + ".\n" + "Porta não utilizada.";
        }
        JOptionPane.showMessageDialog(null, msg, "Porta " + PainelPorta + PortaPorta, JOptionPane.INFORMATION_MESSAGE);
    } catch (SQLException ex)
    {
        JOptionPane.showMessageDialog(null, "MinhaAcao.java [1]\nErro de SQL. \nErro: " + ex.getMessage(), "ERRO!", JOptionPane.ERROR_MESSAGE);
    }
}

}[/code]
Eliminei o método criaAcao, e a classe botao ficou assim:

[code]public class Botao
{

private int SizeX = 0, SizeY = 0, LocationX = 0, LocationY = 0;
private JButton tb1;

public Botao(int sizeX, int sizeY, int locationX, int locationY)
{
    SizeX = sizeX;
    SizeY = sizeY;
    LocationX = locationX;
    LocationY = locationY;
}

public JButton criarBotao(ActionListener action, String PainelPorta, String PortaPorta, int i)
{
    tb1 = new JButton((PainelPorta + PortaPorta));
    tb1.setName((PainelPorta + PortaPorta));
    tb1.setSize(SizeX, SizeY);
    tb1.setMargin(new Insets(2, 2, 2, 2));
    tb1.setLocation(LocationX, LocationY + (i * 25));
    tb1.setFont(new Font("tahoma", 0, 11));
    tb1.addActionListener(action);
    return tb1;
}

}[/code]
Na hora de imprimir os botões, fiz algo assim:

[code]
painelPortasAssociadas.removeAll();
int i = 0;

sql = “Select Painel, NumPorta FROM Portas WHERE LocalDaPorta like '” + ComboLocais.getSelectedItem().toString() + “’ ORDER BY Painel”;
resultado = expressao.executeQuery(sql);
resultado.beforeFirst();

while (resultado.next())
{
painelPortasAssociadas.add(b.criarBotao(new MinhaAcao(resultado.getString(1), resultado.getString(2)), resultado.getString(1), resultado.getString(2), i));
i++;
}

painelPortasAssociadas.repaint();[/code]