POO – AULA 01

Propaganda
POO – AULA 09
 Objetivos da aula




Reforçar conceitos sobre interfaces gráficas com componentes Swing
Introduzir o conceito de evento
Apresentar mais alguns componentes Swing
Compreender o funcionamento do tratamento de eventos
 Recordando...
Na aula passada, vimos como criar uma interface gráfica usando
componentes do pacote Swing. Entretanto a aplicação que desenvolvemos
somente exibia informações, não possuindo entrada de dados. Hoje vamos
estender esse conceito, usando outros componentes típicos de aplicações
gráficas, como botões e caixas de edição. Antes, entretanto, vamos
desenvolver o conceito de tratamento de eventos.
 Tratamento de eventos
As tarefas que um aplicativo gráfico deve realizar são comandadas pelo
usuário através da interação deste com a GUI. É comum clicar sobre um
botão (“OK”, “Enviar” ou “Gravar”, por exemplo) para instruir o aplicativo a
realizar uma tarefa. As aplicações com GUIs são, portanto, baseadas em
eventos, que geralmente são gerados pelo usuário. Quando um usuário
interage com um componente GUI, ele gera um evento, que resulta numa
tarefa a ser executada. Alguns eventos comuns são o clicar em um botão,
o digitar numa caixa de texto ou o selecionar uma opção de uma lista. O
código que realiza uma tarefa em resposta ao evento é chamado de
handler de evento, e o processo total de responder ao evento é conhecido
como tratamento do evento.
 Tratando eventos de componentes Swing
Vamos conhecer dois componentes do pacote javax.swing que possuem
eventos associados: JTextField e JPasswordField.
A classe JTextField estende a classe JTextComponent (javax.swing.text), e
possui recursos comuns aos componentes baseados em texto do Swing.
Este componente serve, normalmente, para a entrada de dados.
A classe JPasswordField estende JTextField adicionando métodos para o
processamento de senhas. Este componente mostra “caracteres eco” à
medida que o usuário digita, escondendo os caracteres digitados.
Quando o usuário, após digitar um texto em um dos componentes acima,
pressionar “Enter”, será gerado um evento que poderá acionar uma tarefa. 1
Antes que um aplicativo possa responder a um evento, é necessário:
1. Criar uma classe que represente o handler do evento e instanciar um
objeto dessa classe (o handler do evento).
2. Implementar uma interface apropriada, conhecida como interface
listener de evento na classe do handler do evento;
3. Registrar o handler do evento, indicando que o objeto de handler do
evento deve ser notificado quando o evento ocorrer.
O componente GUI acionado pelo usuário gera um ActionEvent (pacote
java.awt.event), que é processado pelo objeto handler do evento, que
implementa uma interface ActionListener (pacote java.awt.event).
O aplicativo a seguir utiliza as classes apresentadas para criar e manipular
quatro campos de texto. Quando o usuário digita em um dos campos e
pressiona “Enter”, o aplicativo exibe um caixa de diálogo com o texto
digitado. Observe que o texto só pode ser digitado no componente que
estiver sob “foco”. Um componente recebe o “foco” quando o usuário clica
sobre ele ou quando “passeia” pelos objetos utilizando a tecla “tab”.
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JPasswordField;
import javax.swing.JOptionPane;
public class JanelaTexto extends JFrame{
private JTextField campo1;
private JTextField campo2;
private JTextField campo3;
private JPasswordField campo4;
public JanelaTexto(){
super("Testa caixas de texto");
setLayout(new FlowLayout()); // layout do frame
campo1 = new JTextField(10); //caixa com 10 colunas
add( campo1 ); // adiciona campo1 à janela
campo2 = new JTextField("Campo editável");
add(campo2);
campo3 = new JTextField("Não editável", 10);
campo3.setEditable(false); // desativa edição
add(campo3);
campo4 = new JPasswordField("Senha",10);
add(campo4);
//instancia o objeto handler do evento
TrataEvento handler = new TrataEvento();
2
campo1.addActionListener(handler);//registra handler
campo2.addActionListener(handler);//registra handler
campo4.addActionListener(handler);//registra handler
} // fim do construtor
// classe que implementa o objeto handler do evento
private class TrataEvento implements ActionListener{
public void actionPerformed(ActionEvent evento){
String s = "";
if (evento.getSource() == campo1)
s=String.format("Texto 1: %s",campo1.getText());
else if (evento.getSource() == campo2)
s=String.format("Texto 2: %s",campo2.getText());
else if (evento.getSource() == campo4)
s = String.format("Texto: %s",
new String(campo4.getPassword()));
JOptionPane.showMessageDialog(null, s);
}
} // fim da classe TrataEvento
} // fim da classe JanelaTexto
A largura em pixels de uma coluna de texto depende o tamanho da fonte
atual do campo de texto. Se o texto digitado for mais largo que o campo de
10 colunas do objeto, a parte do texto à direita não ficará visível.
O tratamento de eventos nesse exemplo é realizado por um objeto da
classe TrataEvento.
Quando o usuário pressionar “Enter” em um JTextField ou no
JPasswordField, o componente gera um ActionEvent (pacote
java.awt.event), que é processado por um objeto que implemente a
interface ActionListener (pacote java.awt.event).
Para que o evento no objeto GUI seja atendido é necessário registrar
previamente o objeto handler no objeto GUI.
Na classe acima, foi utilizado o método actionPerformed de um objeto de
tratamento de evento. No caso, a origem dos eventos é o “Enter” nos
campos de texto da janela e, quando isto ocorrer, o sistema cria um objeto
ActionEvent único que contém informações sobre o evento que acabou de
ocorrer, tais como a origem do evento e o texto do campo de texto e passa
este objeto em uma chamada para o método actionPerformed do “ouvinte”
de eventos, ou listener de eventos.
O método getSource() da classe ActionEvent retorna uma referência à
origem do evento e o método getActionCommand, da mesma classe,
retorna o texto do campo de texto.
3
A seguir temos a classe TestaJanelaTexto que utiliza a classe acima.
import javax.swing.JFrame;
public class TestaJanelaTexto {
public static void main( String args[] ) {
JanelaTexto jan = new JanelaTexto ();
jan.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jan.setSize(250, 120);
jan.setVisible(true);
}
}
 Tipos comuns de eventos
Existem diferentes tipos de eventos em uma interface GUI. Ao ocorrer um
evento, as informações sobre o evento são armazenadas em um objeto de
uma classe que estende a classe AWTEvent. A hierarquia abaixo contém
várias classes de eventos do pacote java.awt.event. Estes tipos de eventos
são utilizados tantos em objetos AWT como Swing. Eventos específicos
para objetos Swing são declarados no pacote javax.swing.event.
Object
ActionEvent
EventObject AdjustmentEvent
AWTEvent
ContainerEvent
ItemEvent
FocusEvent
TextEvent
ComponentEvent PaintEvent
WindowEvent
KeyEvent
InputEvent
MouseEvent
O modelo de tratamento que vimos aqui é
conhecido como modelo de delegação de WindowListener
ActionListener
eventos, pois o processamento de um
AdjustmentListener
evento é passado a um objeto particular
ComponentListener
no aplicativo, o objeto listener ou o ouvinte
ContainerListener
de eventos.
FocusListener
Para cada tipo de evento, existe uma
ItemListener
interface ouvinte de eventos. Um ouvinte
KeyListener
de evento é um objeto que implementa
MouseListener
uma ou mais interfaces do pacote
MouseMotionListener
java.awt.event ou javax.swing.event. Veja
TextListener
algumas interfaces na caixa ao lado.
Cada interface ouvinte de eventos especifica os métodos de tratamento de
evento que interessem. Quando ocorre um evento, o componente da
interface com o qual o usuário interagiu informa seus ouvintes registrados,
chamando o método de tratamento de evento adequado de cada ouvinte. 4
 Entendendo o funcionamento de eventos
Registrando eventos
Cada objeto JComponent, por exemplo JTextField, tem uma variável de
instância chamada listenerList que referencia um objeto da classe
EventListenerList do pacote javax.swing.event. Podemos entender
listenerList como um array . Quando a instrução
campo1.addActionListener (handler)
é executada, uma nova entrada que contém uma referência ao objeto
TextFieldHandler é colocada na listenerList do JTextField campo1. Ou seja,
cada componente GUI mantém sua própria lista de ouvintes que foram
registrados para tratar os eventos do componente.
Chamando o handler de evento:
Cada componente GUI suporta vários tipos de eventos: de mouse, de
teclado, etc. Quando um evento ocorre, somente os métodos apropriados
dos ouvintes de eventos são afetados. Cada tipo de evento tem uma ou
mais interfaces ouvintes de eventos correspondentes. ActionEvents são
tratados por ActionListeners, MouseEvents são tratados por
MouseListeners e MouseMotionListeners, e KeyEvents são tratados por
KeyListeners. Quando ocorre um evento, um componente GUI recebe da
JVM um ID do evento que especifica o tipo de evento. O componente GUI
utiliza o ID para decidir o tipo de ouvinte a ser acionado e o método a ser
chamado no objeto ouvinte. Para que isto aconteça, é necessário registrar
um handler de evento no componente GUI para o tipo particular de evento
que seu aplicativo exige, e o componente GUI fará com que o método
apropriado do handler seja chamado.
 O componente JButton
Um botão é um componente que o usuário clica com o mouse para
disparar uma ação específica. Um aplicativo pode utilizar vários tipos de
botões: botões de comando, caixas de seleção e botões de opção.
A classe JanelaBotoes cria 2 JButtons com ícones, e realiza o tratamento
de eventos dos botões em uma única instância da classe TrataBotao.
import
import
import
import
import
import
import
import
java.awt.FlowLayout;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
javax.swing.JFrame;
javax.swing.JButton;
javax.swing.Icon;
javax.swing.ImageIcon;
javax.swing.JOptionPane;
5
public class JanelaBotoes extends JFrame {
private JButton botao1;
private JButton botao2;
public JanelaBotoes() {
super("Testando Botões");
setLayout(new FlowLayout());
botao1 = new JButton("Botão simples");
add(botao1);
Icon bug1 = new ImageIcon(
getClass().getResource("bug1.gif"));
Icon bug2 = new ImageIcon(
getClass().getResource("bug2.gif"));
botao2 = new JButton("Botão com ícone", bug1);
botao2.setRolloverIcon(bug2); //icone de rollover
add(botao2);
TrataBotao handler = new TrataBotao();
botao2.addActionListener(handler); // registra handler
botao1.addActionListener(handler); // registra handler
}
private class TrataBotao implements ActionListener{
public void actionPerformed(ActionEvent evento){
JOptionPane.showMessageDialog (JanelaBotoes.this,
String.format("Você cliclou no : %s",
evento.getActionCommand()));
}
}
}
Os components JButtons, assim como os JTextFields, geram
ActionsEvents que podem ser processados por qualquer objeto
ActionListener. A classe TrataBotao declara o método actionPerformed que
exibe numa caixa de mensagem o rótulo do botão clicado pelo usuário.
A classe TestaJanelaBotoes a seguir completa a aplicação.
import javax.swing.JFrame;
public class TestaJanelaBotoes{
public static void main(String args[]) {
JanelaBotoes Jan = new JanelaBotoes();
Jan.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Jan.setSize( 300, 200 );
Jan.setVisible(true);
}
}
As caixas de mensagens aparecem centralizadas na janela do aplicativo
devido à chamada do método showMessageDialog, utilizar como primeiro
argumento JanelaBotoes.this em vez de null. Este primeiro argumento
6
indica o componente que irá conter (container) a caixa de diálogo.
 Desafio
1. Usando a interface KeyListener e o evento KeyEvent, implemente um
handler para detectar e emitir uma mensagem quando uma tecla for
apertada enquanto o foco estiver no componente botao2.
7
Download