Eventos

Eventos são ações que podem ser realizadas pelos usuários em uma interface gráfica. Em Java Swing, os eventos são tratados por meio de listeners, que são objetos que "escutam" a ocorrência de um evento e executam uma ação em resposta a ele. Existem vários tipos de listeners em Swing, cada um voltado para um tipo específico de evento. Abaixo são apresentados os mais comuns.

ActionListener

O ActionListener é um tipo de listener usado para tratar eventos relacionados a botões e outros componentes que geram eventos de ação, como os menus. Quando um usuário clica em um botão, por exemplo, um evento de ação é gerado, e o ActionListener associado a esse botão é acionado, executando a ação definida para ele.

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

public class MeuFrame extends JFrame implements ActionListener {
    private JButton botao;

    public MeuFrame() {
        setTitle("Exemplo de ActionListener");
        setSize(300, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel painel = new JPanel(new FlowLayout());

        botao = new JButton("Clique aqui!");
        botao.addActionListener(this);
        painel.add(botao);

        add(painel);
        setVisible(true);
    }

    public void actionPerformed(ActionEvent evento) {
        if (evento.getSource() == botao) {
            JOptionPane.showMessageDialog(this, "Você clicou no botão!");
        }
    }

    public static void main(String[] args) {
        MeuFrame frame = new MeuFrame();
    }
}

ChangeListener

O ChangeListener é um tipo de listener usado para tratar eventos de mudança de estado em componentes como o JSlider e o JCheckBox. Quando o usuário interage com um desses componentes e seu estado é alterado, um evento de mudança de estado é gerado, e o ChangeListener associado a esse componente é acionado, executando a ação definida para ele.

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

public class MeuFrame extends JFrame implements ChangeListener {
    private JSlider slider;

    public MeuFrame() {
        setTitle("Exemplo de ChangeListener");
        setSize(300, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel painel = new JPanel(new FlowLayout());

        slider = new JSlider(0, 100, 50);
        slider.addChangeListener(this);
        painel.add(slider);

        add(painel);
        setVisible(true);
    }

    public void stateChanged(ChangeEvent evento) {
        if (evento.getSource() == slider) {
            int valor = slider.getValue();
            setTitle("Valor: " + valor);
        }
    }

    public static void main(String[] args) {
        MeuFrame frame = new MeuFrame();
    }
}

FocusListener

O FocusListener é um tipo de listener usado para tratar eventos relacionados a alterações de foco em componentes. Quando um componente perde o foco ou ganha o foco, um evento é gerado, e o FocusListener associado a esse componente é acionado, executando a ação definida para ele.

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

public class FocusListenerExample extends JFrame implements FocusListener {
    private JTextField textField;
    private JLabel label;

    public FocusListenerExample() {
        setTitle("Exemplo de FocusListener");
        setSize(300, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = new JPanel(new GridLayout(2, 1));

        textField = new JTextField();
        textField.addFocusListener(this);

        // Cria um JLabel inicialmente com o texto "Label"
        label = new JLabel("Label");

        // Adiciona os componentes ao frame
        panel.add(textField);
        panel.add(label);

        add(panel);

        // Configura o tamanho e a visibilidade do frame
        setSize(200, 100);
        setVisible(true);
    }

    public void focusGained(FocusEvent e) {
        // Não faz nada quando o campo ganha o foco
    }

    public void focusLost(FocusEvent e) {
        // Altera o texto do JLabel para o valor atual do JTextField quando ele perde o foco
        label.setText(textField.getText());
    }

    public static void main(String[] args) {
        FocusListenerExample ex = new FocusListenerExample();
    }
}

Múltiplos eventos

Quando necessário processar mais de um evento, deixa de ser uma boa prática implementar o listener direto na classe do frame como nos exemplos acima. Nesses casos temos algumas formas de fazer.

Repetidos IFs

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class MeuFrame extends JFrame implements ActionListener {

    private JButton botaoInfo;
    private JButton botaoAlerta;
    private JButton botaoErro;
    
    public MeuFrame() {
        super("Exemplo de Botões com Diálogos");
        
        // Configura o layout do frame para FlowLayout
        setLayout(new FlowLayout());
        
        // Cria os botões
        botaoInfo = new JButton("Informação");
        botaoAlerta = new JButton("Alerta");
        botaoErro = new JButton("Erro");
        
        // Adiciona os botões ao frame
        add(botaoInfo);
        add(botaoAlerta);
        add(botaoErro);
        
        // Registra o frame como ouvinte dos eventos de clique nos botões
        botaoInfo.addActionListener(this);
        botaoAlerta.addActionListener(this);
        botaoErro.addActionListener(this);
        
        // Configura as propriedades do frame
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(300, 100);
        setVisible(true);
    }
    
    @Override
    public void actionPerformed(ActionEvent e) {
        // Verifica qual botão foi clicado
        if (e.getSource() == botaoInfo) {
            // Exibe um diálogo de informação
            JOptionPane.showMessageDialog(this, "Mensagem de Informação", "Informação", JOptionPane.INFORMATION_MESSAGE);
        } else if (e.getSource() == botaoAlerta) {
            // Exibe um diálogo de alerta
            JOptionPane.showMessageDialog(this, "Mensagem de Alerta", "Alerta", JOptionPane.WARNING_MESSAGE);
        } else if (e.getSource() == botaoErro) {
            // Exibe um diálogo de erro
            JOptionPane.showMessageDialog(this, "Mensagem de Erro", "Erro", JOptionPane.ERROR_MESSAGE);
        }
    }
    
    public static void main(String[] args) {
        new MeuFrame();
    }

}

Neste exemplo utilizamos a fonte do evento a partir do método getSource() que retorna o componente que gerou o evento. A partir disso são criados um if/else para cada botão esperado.

Essa opção pode ser um problema quando houverem muitos botões pois haverão muitos ifs encadeados e isso não é uma boa prática.

Inner Class

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

public class MeuFrame extends JFrame {

    public MeuFrame() {
        super("Exemplo de Formulário com Diálogos");

        // Cria um painel com FlowLayout
        JPanel painel = new JPanel(new FlowLayout());

        // Cria os componentes
        JButton infoButton = new JButton("Info");
        JButton alertButton = new JButton("Alerta");
        JButton erroButton = new JButton("Erro");

        // Adiciona os componentes ao painel
        painel.add(infoButton);
        painel.add(alertButton);
        painel.add(erroButton);

        // Adiciona o painel ao frame
        this.getContentPane().add(painel);

        // Cria os listeners para os botões
        infoButton.addActionListener(new InfoActionListener());
        alertButton.addActionListener(new AlertActionListener());
        erroButton.addActionListener(new ErrorActionListener());

        // Configurações do frame
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.pack();
        this.setVisible(true);
    }

    public static void main(String[] args) {
        new MeuFrame();
    }
    
    public class ErrorActionListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            JOptionPane.showMessageDialog(MeuFrame.this,
                    "Mensagem de erro",
                    "Erro",
                    JOptionPane.ERROR_MESSAGE);
        }
    }
    
    public class AlertActionListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            JOptionPane.showMessageDialog(MeuFrame.this,
                    "Mensagem de alerta",
                    "Alerta",
                    JOptionPane.WARNING_MESSAGE);
        }
    }
    
    public class InfoActionListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            JOptionPane.showMessageDialog(MeuFrame.this,
                    "Mensagem de informação",
                    "Info",
                    JOptionPane.INFORMATION_MESSAGE);
        }
    }
}

No exemplo acima são declaradas diferentes classes internas para cada listener permitindo que sejam adicionados unitariamente para cada componente nesse contexto.

Anonymous Class

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

public class MeuFrame extends JFrame {

    public MeuFrame() {
        super("Exemplo de Formulário com Diálogos");

        // Cria um painel com FlowLayout
        JPanel painel = new JPanel(new FlowLayout());

        // Cria os componentes
        JButton infoButton = new JButton("Info");
        JButton alertButton = new JButton("Alerta");
        JButton erroButton = new JButton("Erro");

        // Adiciona os componentes ao painel
        painel.add(infoButton);
        painel.add(alertButton);
        painel.add(erroButton);

        // Adiciona o painel ao frame
        this.getContentPane().add(painel);

        // Cria os listeners para os botões
        infoButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(MeuFrame.this,
                        "Mensagem de informação",
                        "Info",
                        JOptionPane.INFORMATION_MESSAGE);
            }
        });

        alertButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(MeuFrame.this,
                        "Mensagem de alerta",
                        "Alerta",
                        JOptionPane.WARNING_MESSAGE);
            }
        });

        erroButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(MeuFrame.this,
                        "Mensagem de erro",
                        "Erro",
                        JOptionPane.ERROR_MESSAGE);
            }
        });

        // Configurações do frame
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.pack();
        this.setVisible(true);
    }

    public static void main(String[] args) {
        new MeuFrame();
    }
}

No exemplo acima são utilizadas classes anônimas para declarar e instanciar pontualmente cada ActionListener que separadamente. Dessa maneira, cada botão tem a sua ação distinta e não é necessário descrever tantos if/else consecutivos.

Referências

Last updated