Como criar evento em JButton, em tempo de execução? [Resolvido]

Boa tarde.

Sou novo no fórum, e também em Java…

No entanto, curso Tecnologia em Análise e Desenvolvimento de Sistemas, e…

Tenho um “trabalhinho” a fazer e java com conexão a banco de dados, que estou fazendo, mas no andamento do trabalho vai surgindo uma coisa e outra a ser feito e duvidas vão surgindo!!!

Criei alguns métodos estáticos para serem chamados em rotinas que fossem comum, para que não fosse necessário ficar reescrevendo.

Nas minhas delas (aplicação desktop), em todas elas estou configurando a mesma aparência, e para isso, manualmente coloquei ações em: FocusGained, FocusLost, MouseEntered e MouseExited, para cada botão.

Então tive a idéia de tentar criar um método estático, e fazer um loop para adicionar os eventos, a cada botão, em tempo de execução.

Obs.: Não se isso é possível, mas tentei e não funcionou. Só não sei se é por não ser possível ou porque fiz errado!!

Abaixo, esta o código que tentei fazer:

public static void setActionButtons(Container container) {

    for (int i = 0; i < container.getComponentCount(); i++) {

        Component c = container.getComponent(i); // pega o componente container

        if (c instanceof JTextField) {
            JButton bt = (JButton) c;

            // adiciona eventos ao botão, em tempo de execução
            bt.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent evt) {
                    //JOptionPane.showMessageDialog(null, "teste");
                }

                public void FocusGained(FocusEvent evt) {
                    bt.setContentAreaFilled(true);
                }

                public void FocusLost(FocusEvent evt) {
                    bt.setContentAreaFilled(false);
                }

                public void MouseEntered(FocusEvent evt) {
                    bt.setContentAreaFilled(true);
                }

                public void MouseExited(FocusEvent evt) {
                    bt.setContentAreaFilled(false);
                }

            });

        }
    }
} // fim setActionButtons

E estava chamando desta forma, no meu JFrame e/ou JInternalFrame:

Tools.setActionButtons(pnBotao);

Tools: Classe que contêm o método.
pnBotao: JPainel que contêm os JButtons.

Tentei pegar todo esse método e colocar dentro da própria classe do frame, para ver se funcionava (nesse caso teria que replicar para cada frame, o que eu não gostaria de fazer), mas também não funcionou.

Bom, minha dúvida é…

É possível fazer isso que estou querendo, se sim, como proceder?

Obrigado.

Perfeito, só uma dica pra falar mais bonito: Você não adiciona eventos aos componentes.
Você adiciona (ou registra) Listeners para tratar determinados eventos que são disparados pelo componente.

Você fez errado.

Se ‘c’ for um ‘JTextField’, você vai tratá-lo como se fosse um ‘JButton’?
Logicamente falando, isso não faz o menor sentido e na prática irá ocorrer um ClassCastException.
Seu if precisa ser assim:

if (c instanceof JButton) {
    JButton bt = (JButton) c;

Somente o método actionPerformed pertence à interface ActionListener, os outros métodos que você implementou não irão servir pra nada.

Para tratar focusGained e focusLost, você deve registrar um FocusListener.

Para tratar mouseEntered e mouseExited, você deve registrar um MouseListener

1 curtida

Então, isso do JTextField estar no lugar do JButton, foi coisa dos Ctrl+C / Ctrl+V. As vezes acontece!!!

Copiei um trecho de outro lugar que estava funcionando, onde é feito uma varredura para verificar se há JTextFields em branco, enfim…

Agora funcionou, ficou assim:

public static void setActionButtons(Container container) {

    for (int i = 0; i < container.getComponentCount(); i++) {

        Component c = container.getComponent(i); // pega o componente container

        if (c instanceof JButton) {
            JButton bt = (JButton) c;

            //-------------------------------------------------
            // FOCUS
            bt.addFocusListener(new FocusListener() {
                @Override
                public void focusGained(FocusEvent e) {
                    bt.setContentAreaFilled(true);
                }

                @Override
                public void focusLost(FocusEvent e) {
                    bt.setContentAreaFilled(false);
                }
            });

            //-------------------------------------------------
            // MOUSE
            bt.addMouseListener(new MouseListener() {
                @Override
                public void mouseEntered(MouseEvent e) {
                    bt.setContentAreaFilled(true);
                }

                @Override
                public void mouseExited(MouseEvent e) {
                    bt.setContentAreaFilled(false);
                }

                //-----------------
                // não utilizados
                // comentados para não "dar" erro...
                @Override
                public void mouseClicked(MouseEvent e) {
                    //throw new UnsupportedOperationException("Not supported yet.");
                }

                @Override
                public void mousePressed(MouseEvent e) {
                    //throw new UnsupportedOperationException("Not supported yet.");
                }

                @Override
                public void mouseReleased(MouseEvent e) {
                    //throw new UnsupportedOperationException("Not supported yet.");
                }
            });

        } // fim if instaceof
    } // fim for
} // fim setActionButtons

Desconhecia FocusListener e MouseListener!

Mas, agora mais uma dúvida!

Ao registrar FocusListener e MouseListener, é obrigado a implementar todos métodos abstratos.

Com FocusListener , só teve dois métodos e foram que eu utilizei mesmo, então ok.

Mas, com MouseListener são cinco.

Os que não utilizei, comentei a linha do código para não dar erro, estava dando um exception.

Então fiz, como abaixo:

            @Override
            public void mouseReleased(MouseEvent e) {
                //throw new UnsupportedOperationException("Not supported yet.");
            }

Mas fica a dúvida…

Por não implementar esse método, posso ter algum problema?

E, também, caso precise que um botão tenha um evento em particular, por ter passado por este que criei ( setActionButtons(Container container) ), pode gerar algum erro?

Por exemplo, fiz esse método para executar estas operações em particular. Mas poderia muito bem precisar que executasse uma ação apenas em um botão específico quando, sei lá…, houvesse um “mouseEntered” em um botão, sendo que o mesmo recebeu um “override” do meu método.

Apenas esta dúvida, a anterior resolvido.

Obrigado.

Quando você implementa uma interface, você precisa implementar todos os métodos que ela define. Entenda que uma interface é um contrato que define as operações que uma classe deve suportar.

Sobre o MouseListener, ao invés de implementar diretamente a interface MouseListener, você pode estender a classe abstrata MouseAdapter e só sobrescrever os métodos que te intertessam.
Exemplo:

    bt.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseEntered(MouseEvent e) {
                bt.setContentAreaFilled(true);
            }

            @Override
            public void mouseExited(MouseEvent e) {
                bt.setContentAreaFilled(false);
            }
    });

Não, você não quer tratar aquele evento, então não faz nada. :slight_smile:

Não. Além do mais, você pode adicionar quantos listeners desejar, cada um pode fazer uma operação diferente quando o mesmo evento é disparado.

1 curtida

Entendi.

Obrigado staroski pela atenção.

[Resolvido]