As aplicações em geral precisam de alguns eventos para o funcionamento completo do programa. Normalmente as GUIs do Java são baseadas em eventos, que são tarefas realizadas quando um usuário faz a interação com algum componente GUI, convertendo as ações do usuário em eventos, como por exemplo:

  • Quando ocorre uma ação (ActionEvent);
  • Clique do mouse (MouseEvent);
  • Apertar em uma tecla (KeyEvent);
  • Fechar uma janela (WindowEvent);

As tarefas de respostas realizadas em um evento são conhecidas como handler de evento e o processo total de responder a eventos é conhecido como tratamento de evento. Para cada tipo de evento precisa ser implementada uma interface de escuta.

As informações de evento são armazenadas em um objeto de uma classe que estende AWT.Event. Veja abaixo na Figura 1 a hierarquia de eventos referente ao pacote java.awt.

Classes de evento do pacote java.awt
Figura 1. Classes de evento do pacote java.awt

Existem três elementos para o funcionamento d1o tratamento de evento que são:

  • Origem do Evento: é o componente GUI com qual o usuário interage.
  • Objeto do Evento: contém os dados do evento invocado, sendo como uma referência à origem do evento e quaisquer informações específicas do evento que podem ser exigidas pelo ouvinte para testar o evento.
  • Ouvinte do Evento: é um objeto que é notificado pela origem de evento quando um evento ocorre.

Na Figura 2 são mostradas as interfaces ouvintes de eventos dos pacotes javax.swing.event.

Interfaces listener de eventos
Figura 2. Interfaces listener de eventos

Lembrando que as interfaces providas da classe Listener podem ter um ou mais métodos de tratamento de evento que devem ser declarados na classe que implementa a interface.

Sendo evento ouvinte

Quando existe a intenção de uma ação do usuário sobre algum componente, é necessário o componente saber que há esse interesse, sendo assim é implementado a interface ActionListener e usado o método addActionListener() sendo passado como parâmetro a palavra “this”, é a referência do objeto da classe que implementa a interface ActionListener, neste caso ela mesma. Após isso é preciso saber uma maneira de chamar o componente quando algum evento ocorrer, sendo que o componente irá chamar o método da interface de escuta, ActionListener.

Para fazermos um tratador de eventos precisamos de três ações básicas:

  1. Especificar uma classe que implemente uma interface de ActionListener:
    public class CapturaEvento implements ActionListener {
  2. Executar um código que registre uma instância desta classes como um listener de um ou mais componentes:
    botao.addActionListener(this);
  3. Definir o método de manipulação de eventos interface ActionListener:
    public void actionPerformed(ActionEvent evento) {
 
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

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

public class CapturaEventoBotao implements ActionListener {
	
	private JButton botao;
	
	public void janela(){
		JFrame frame = new JFrame();
		botao = new JButton();
		
		//REGISTRA O EVENTO
		botao.addActionListener(this);

		frame.getContentPane().add(botao);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(300,100);
		frame.setVisible(true);
	}
	
	@Override
	public void actionPerformed(ActionEvent evento) {
		botao.setText("Botão foi clicado!");
		
		//ALTERA A FONTE 
		botao.setFont(new Font("SansSerif", Font.BOLD, 20));	
	}
	
	public static void main(String[] args) {
		CapturaEventoBotao captura = new CapturaEventoBotao();
		captura.janela();
	}
}
Listagem 1. Captura o evento de um botão

Handler de Evento

Quando um evento acontece, é realizado o despacho (dispatching) para os ouvintes apropriados. Esse despacho é o processo em que o componente GUI chama um método de tratamento de evento em cada um de seus ouvintes, sendo registrados para o tipo de evento ocorrido.

A ocorrência de um evento faz com que o componente receba um ID único de evento. Esse ID especifica o tipo de evento. Então o componente pega esse ID para decidir qual tipo de ouvinte irá ser útil para o evento que deverá ser despachado, decidindo qual o método que vai chamar para cada objeto listener.

O evento é despachado por todas as decisões que são tratadas para o usuário através dos componentes GUI. Sendo necessário ser feito, pois precisa ser registrado um handler de evento para o tipo particular de evento que o aplicativo exige. O componente vai assegurar que o método apropriado do handler de evento é chamado quando o evento ocorrer. Abaixo ilustramos alguns exemplos de componentes GUI e manipulações de alguns eventos.

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 ButtonFrame2 extends JFrame{
	
	private JButton botaoPrata;
	private JButton botaoOuro;
	
	//BUTTONFRAME ADICIONA JBUTTONS AO JFRAME
	public ButtonFrame2()
	{
		super("Testando Botões");
		setLayout(new FlowLayout()); //CONFIGURA O LAYOUT DE FRAME
		
		botaoPrata = new JButton("Prata"); //BOTÃO COM TEXTO
		add(botaoPrata); //ADICIONA botaoPrata AO JFRAME
		
		botaoOuro = new JButton("Ouro");
		add(botaoOuro); //ADICIONA botaoOuro AO JFRAME
		
		//CRIA NOVO BUTTON HANDLER PARA TRATAMENTO DE EVENTO DE BOTÃO
		ButtonHandler handler = new ButtonHandler();
		botaoOuro.addActionListener(handler);
		botaoPrata.addActionListener(handler);		
		
	}
	
	//CLASSE INTERNA PARA TRATAMENTO DO BOTÃO
	public class ButtonHandler implements ActionListener
	{
		//TRATA EVENTO DO BOTÃO
		public void actionPerformed(ActionEvent event)
		{
			JOptionPane.showMessageDialog(ButtonFrame2.this, String.format("Você pressionou: %s", event.getActionCommand()));
		}
	}
}
Listagem 2. Criação de botões e aplicação de eventos

Apenas comentando que no código da Listagem 2 foi criada uma classe interna chamada ButtonHandler. Uma classe interna é criada para capturar os eventos de dois ou mais componentes diferentes. A classe interna pode usar todos os métodos e variáveis da classe externa.

import javax.swing.JFrame;

public class TestaButton {

	public static void main(String[] args) {
		
		ButtonFrame2 buttonFrame = new ButtonFrame2();
		buttonFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		buttonFrame.setSize(275, 210);
		buttonFrame.setVisible(true);

	}
}
Listagem 3. Testa a classe ButtonFrame2

Eventos nos TextField

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

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

public class TextFieldFrame extends JFrame {

	private JTextField textField1;
	private JTextField textField2;
	private JTextField textField3;
	private JPasswordField passwordField;
	
	//CONSTRUTOR TEXTFIELDFRAME ADICIONA JTEXTDFIELDS A JFRAME
	public TextFieldFrame()
	{
		super("Testando JTextField e JPasswordField");
		setLayout(new FlowLayout());
		
		//CONSTRÓI TEXTFIELD COM 10 COLUNAS
		textField1 = new JTextField(10);		
		add(textField1); //ADICIONA TEXTFIELD2 AO JFRAME
		
		textField2 = new JTextField("Entre com o texto aqui");
		add(textField2);
		
		//CONSTRÓI TEXTFIELD COM TEXTO PADRÃO E 21 COLUNAS
		textField3 = new JTextField("Campo não editável",21);
		textField3.setEditable(false); //DESATIVA EDIÇÃO
		add(textField3);
		
		//CONSTRÓI PASSWORDFIELD COM TEXTO PADRÃO
		passwordField = new JPasswordField("Texto Escondido");
		add(passwordField); //ADICIONA PASSWORDFIELD AO JFRAME
		
		//HANDLERS DE EVENTO REGISTRADORES
		TextFieldHandler handler = new TextFieldHandler();
		textField1.addActionListener(handler);
		textField2.addActionListener(handler);
		textField3.addActionListener(handler);
		passwordField.addActionListener(handler);
		
	}
	
	//CLASSE INTERNA PRIVATE PARA TRATAMENTO DE EVENTO
	private class TextFieldHandler implements ActionListener
	{
		//PROCESSA EVENTOS DE CAMPO DE TEXTO
		public void actionPerformed(ActionEvent event){
			
			String string = "";	
			
			//USUÁRIO PRESSIONOU ENTER NO JTEXTFIELD TEXTFIELD1
			if(event.getSource() == textField1)
				string = String.format("textField1: %s", 
				event.getActionCommand());
			
			//USUÁRIO PRESSIONOU ENTER NO JTEXTFIELD TEXTFIELD2
			else if(event.getSource() == textField2)
				string = String.format("textField2: %s", 
				event.getActionCommand());
			
			//USUÁRIO PRESSIONOU ENTER NO JTEXTFIELD TEXTFIELD3
			else if(event.getSource() == textField3)
				string = String.format("textField3: %s", 
				event.getActionCommand());
			
			//USUÁRIO PRESSIONOU ENTER NO JTEXTFIELD PASSWORDFIELD
			else if(event.getSource() == passwordField)
				string = String.format("passowordField: %s", 
				event.getActionCommand());
			
			//EXIBE O CONTEÚDO DE JTEXTFIELD
			JOptionPane.showMessageDialog(null, string);
			
		}
	}
}
Listagem 4. Eventos nos campos de textos
import javax.swing.JFrame;

public class TestaTextField {

	public static void main(String[] args) {

		TextFieldFrame textFieldFrame = new TextFieldFrame();
		textFieldFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		textFieldFrame.setSize(350,200);
		textFieldFrame.setVisible(true);
		
	}

}
Listagem 5. Classe testadora TextFieldFrame

Conclusão

Para concluir esse artigo, abaixo é apresentado um resumo de algumas ações para servir como base de consulta.

  • Sempre quando for criar um componente comece com uma Janela (JFrame) – Jframe frame = new Jframe();
  • Para adicionar os componentes gráficos dentro de um Jframeframe.getContentPane().add(nomeComponenteInstanciado);
  • Para ouvir um evento, sempre registrar o interesse em uma origem de evento.
  • Para registrar e ouvir ActionEvents de um componente – nomeDoComponente.addActionListener(this);
  • Implemente a interface de escuta e insira todos os métodos de manipulação de eventos que essa interface tem.
    public void actionPerformed(ActionEvent evento){
    //DEFINE OS ESTADOS DOS COMPONENTES
    }