• Nenhum resultado encontrado

Cada categoria de evento exige uma interface apropriada que deve ser implementada pela classe tratadora do evento.

N/A
N/A
Protected

Academic year: 2021

Share "Cada categoria de evento exige uma interface apropriada que deve ser implementada pela classe tratadora do evento."

Copied!
29
0
0

Texto

(1)

Modelo de Eventos

• 

Em uma GUI, quando o usuário realiza uma ação qualquer, tal como clicar

sobre um botão ou preencher uma caixa de texto, um

evento

é disparado

pelo componente com o qual o usuário interagiu.

• 

Eventos são

objetos

que descrevem o que aconteceu na interação entre o

usuário e o componente. Os tipos de evento estão definidos nos pacotes

java.awt.event

e

javax.swing.event

.

• 

Cada componente a partir do qual um evento se originou, deve propagar o

evento para uma ou mais classes chamadas ouvidoras (

listeners

). As

classes ouvidoras contêm os tratadores de eventos que recebem e

processam o evento.

• 

Os

objetos tratadores de eventos

devem ser registrados aos componentes

da interface gráfica que desejam ouvir (e tratar). Quando ocorre um evento

em um componente, somente os objetos registrados a este componente

recebem a informação de que o evento ocorreu podendo, portanto, tratá-lo

adequadamente.

• 

Quando um evento ocorre, o componente GUI com o qual o usuário

interagiu notifica todos os seus ouvidores registrados, chamando o método

de tratamento de evento apropriado de cada ouvidor.

(2)

• 

A maioria dos componentes de GUI pode disparar mais de um tipo de

evento. Com as classes ouvidoras de eventos pode-se distribuir o

processamento desses eventos, ou seja, podem existir diversas classes para

processar os eventos.

• 

Para processar um evento ocorrido em uma GUI deve-se:

• 

Registrar um ouvidor (

listener

) de eventos. Listeners são classes que

implementam a interface

EventListener

. Existem subclasses desta classe

para cada tipo de componente.

• 

Implementar um tratador (

handler

) de eventos.

• 

Associado a cada evento existe uma

interface ouvidora

apropriada. Esta

interface estabelece quais métodos devem ser definidos na classe tratadora

do evento (a classe que

implementa os métodos

apropriados e que

encontra-se registrada como tratadora do evento).

• 

Exemplo

: classes que implementam a interface

ActionListener

devem

implementar o método

actionPerformed(ActionEvent)

e podem ser

registradas para tratar

ações

(um clique sobre um botão, por exemplo) que

ocorrem na GUI.

(3)

Interfaces para Tratamento de Eventos

• 

Cada categoria de evento exige uma interface apropriada que deve ser

implementada pela classe tratadora do evento.

Hierarquia de Interfaces

• 

A implementação dessas interfaces implica em implementar seus métodos

abstratos. Todos os métodos recebem como parâmetro um objeto de uma

subclasse de

java.awt.event

. Por exemplo: o método

actionPerformed

da

interface

ActionListener

recebe como parâmetro um objeto da classe

ActionEvent

.

java.util.EventListener

KeyListener

MouseListener

MouseMotionListener

TextListener

WindowListener

ActionListener

ComponentListener

AdjustmentListener

ContainerListener

FocusListener

ItemListener

(4)

Hierarquia de Eventos

java.lang.Object

java.util.EventObject

java.awt.AWTEvent

java.awt.event.AdjustmentEvent

java.awt.event.ItemEvent

java.awt.event.TextEvent

java.awt.event.ComponentEvent

java.awt.event.KeyEvent

java.awt.event.MouseEvent

java.awt.event.InputEvent

java.awt.event.InputEvent

java.awt.event.KeyEvent

java.awt.event.MouseEvent

java.awt.event.ActionEvent

(5)

Alguns Métodos Tratadores de Eventos

Evento

Interface

Métodos

Ação

ActionListener

actionPerformed(ActionEvent)

Item

ItemListener

itemStateChanged(ItemEvent)

Lista

ListSelectionListener

valueChanged(ListSelectionEvent)

Mouse

MouseListener

mousePressed(MouseEvent)

mouseReleased(MouseEvent)

mouseEntered(MouseEvent)

mouseExited(MouseEvent)

mouseClicked(MouseEvent)

Movimento

do Mouse

MouseMotionListener

mouseDragged(MouseEvent)

mouseMoved(MouseEvent)

Tecla

KeyListener

keyPressed(KeyEvent)

keyReleased(KeyEvent)

keyTyped(KeyEvent)

Foco

FocusListener

focusGained(FocusEvent)

focusLost(FocusEvent)

(6)

Evento

Interface

Métodos

Ajuste

AdjustmentListener

adjustmentValueChanged(AdjustmentEvent)

Componente

ComponentListener

componentMoved(ComponentEvent)

componentHiden(ComponentEvent)

componentResized(ComponentEvent)

componentShown(ComponentEvent)

Janela

WindowListener

windowClosing(WindowEvent)

windowOpened(WindowEvent)

windowIconnified(WindowEvent)

windowDeiconified(WindowEvent)

windowClosed(WindowEvent)

windowActivated(WindowEvent)

windowDeactivated(WindowEvent)

Container

ContainerListener

componentAdded(ContainerEvent)

componentRemoved(ContainerEvent)

Texto

TextListener

textValueChanged(TextEvent)

(7)

Exemplo 1: Botão com tratador de eventos

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

public class Exemplo1 extends JFrame {

public Exemplo1() {

JFrame frame = new JFrame("Botão com tratador de eventos"); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.setSize(320,120);

JPanel panel = new JPanel();

JButton botao = new JButton("OK"); panel.add(botao);

Container c = frame.getContentPane(); c.add(panel);

// Registrar o tratador de eventos

botao.addActionListener(new TrataEvento()); frame.setVisible(true);

}

}

Não esquecer do método main().

TrataEvento é a classe tratadora de eventos. Esta classe deve implementar o método

actionPerformed(ActionEvent e). Note que o

tratador de evento registrado para esse botão é um

objeto desta classe tratadora de evento.

(8)

Classe Tratadora de Eventos

Reparar que:

• 

A classe tratadora de eventos deve implementar a interface

ActionListener

, ou

seja, implementar o método

actionPerformed(ActionEvent e)

. O parâmetro

desse método possui diversos métodos que ajudam a identificar qual foi o

objeto que gerou o evento.

• 

O método

getActionCommand()

para um botão retorna a legenda (

caption

) do

botão. Mas, e se existissem dois botões com a mesma legenda na interface

gráfica?

import java.awt.event.*;

public class TrataEvento implements ActionListener {

public void actionPerformed(ActionEvent e) {

System.out.println("Voce clicou no botao " + e.getActionCommand()); }

}

(9)

• 

A própria classe que constrói a interface gráfica pode ser a classe tratadora de

eventos: basta que esta classe

implemente

a interface

ActionListener

.

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

public class Exemplo1a extends JFrame implements ActionListener

{

public Exemplo1a() {

JFrame frame = new JFrame("Botão com tratador de eventos"); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.setSize(320,120);

JPanel panel = new JPanel();

JButton botao = new JButton("OK"); panel.add(botao);

Container c = frame.getContentPane(); c.add(panel);

// Registrar o tratador de eventos botao.addActionListener(this); frame.setVisible(true);

} Note que, desta forma, o tratador de evento registrado

para esse botão é um objeto desta própria classe (this).

(10)

• 

Note que a classe

Exemplo1a

, além de construir a interface gráfica,

implementa a interface

ActionListener

, ou seja, é também uma classe

tratadora de eventos de ação. A implementação desta interface consiste em

implementar o método

actionPerformed()

.

public void actionPerformed(ActionEvent e) {

System.out.println("Voce clicou no botao " + e.getActionCommand()); }

public static void main(String[] args) {

Exemplo1a e = new Exemplo1a();

e.addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e) { System.exit(0); } } ); } }

(11)

Exemplo 2: Vários botões com mesma legenda

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

public class Exemplo2 extends JFrame { public Exemplo2() {

JFrame frame = new JFrame("Botões com mesma legenda"); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.setSize(320,120);

JPanel panel = new JPanel(); JButton b1 = new JButton("OK"); b1.setName("Botão1");

JButton b2 = new JButton("OK"); b2.setName("Botão2");

panel.add(b1); panel.add(b2);

Container c = frame.getContentPane(); c.add(panel);

// Registrar o tratador de eventos

b1.addActionListener(new TrataEvento2()); b2.addActionListener(new TrataEvento2()); frame.setVisible(true);

}

} Precisa ainda lembrar de incluir o método main()?

Exemplo2.java

Notar que os dois botões tem o mesmo caption, mas os nomes

dos objetos são diferentes. Assim

será possível dar um tratamento diferente para cada botão.

(12)

Nova Classe Tratadora de Eventos

• 

Portanto, não é preciso construir uma classe tratadora de eventos para cada

componente da GUI. Uma única classe pode tratar os eventos originados por

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

public class TrataEvento2 implements ActionListener {

public void actionPerformed(ActionEvent e) {

JButton b = (JButton)e.getSource(); String nome = b.getName();

if (nome.equals("Botão1")) {

System.out.println("Voce clicou no Botão 1"); }

if (nome.equals("Botão2")) {

System.out.println("Voce clicou no Botão 2"); }

} }

TrataEvento2.java

O método getSource() retorna o objeto que deu origem ao evento (no caso, um botão).

(13)

Exemplo 3: Tratamento de eventos na própria classe da aplicação

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

public class Exemplo3 extends JFrame implements ActionListener {

public Exemplo3() {

JFrame frame = new JFrame("Tratamento na própria classe"); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.setSize(320,120);

JPanel panel = new JPanel(); JButton b1 = new JButton("OK"); b1.setName("Botão1");

JButton b2 = new JButton("OK"); b2.setName("Botão2"); panel.add(b1); panel.add(b2); Container c = frame.getContentPane(); c.add(panel); b1.addActionListener(this); b2.addActionListener(this); frame.setVisible(true); } Exemplo3.java

Notar que o objeto tratador de eventos é um objeto da própria classe (this).

Para ser uma classe tratadora de eventos, deve implementar a interface ActionListener.

(14)

• 

A classe, portanto, deve implementar o método

actionPerformed

...

public void actionPerformed(ActionEvent e) {

JButton b = (JButton)e.getSource(); String nome = b.getName();

if (nome.equals("Botão1")) {

System.out.println("Voce clicou no Botao 1"); }

if (nome.equals("Botão2")) {

System.out.println("Voce clicou no Botão 2"); }

}

public static void main(String[] args) {

Exemplo3 e = new Exemplo3();

e.addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent we) {

System.exit(0); }});

(15)

Exemplo 4: Múltiplos tratadores de eventos

• 

A estrutura de eventos de Java permite que diversos ouvidores sejam

definidos para um único componente. Se um evento for gerado pelo

componente todos os tratadores registrados serão chamados.

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

public class Exemplo4 extends JFrame

implements MouseListener, MouseMotionListener {

public Exemplo4() {

JFrame frame = new JFrame("Diversos tratadores de eventos"); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.setSize(320,120);

JLabel label = new JLabel("Este frame tem dois ouvidores"); Container c = frame.getContentPane();

c.add(label);

// Registrar os tratadores para o frame frame.addMouseListener(this);

frame.addMouseMotionListener(this); frame.setVisible(true);

}

Exemplo4.java

A classe implementa duas interfaces. Todos os métodos dessas 2 interfaces devem ser implementados.

Note que existem dois tratadores registrados para o objeto frame.

(16)

// Métodos da interface MouseListener

public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {

System.out.println("O mouse está na janela!"); }

public void mouseExited(MouseEvent e) {

System.out.println("O mouse saiu da janela!"); }

public void mouseClicked(MouseEvent e) {

System.out.println("O mouse foi clicado!"); }

// Métodos da interface MouseMotionListener

public void mouseDragged(MouseEvent e) {

System.out.println("Movendo: X=" + e.getX() + " Y=" + e.getY()); }

public void mouseMoved(MouseEvent e) {} public static void main(String[] args) { Exemplo4 janela = new Exemplo4();

janela.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0);

}}); }

Note que todos os métodos das interfaces precisam ser

implementados, mesmo

(17)

Exemplo 5: Alguns componentes Swing e seus eventos

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

public class Exemplo5 extends JFrame {

public Exemplo5() {

JFrame frame = new JFrame("Componentes Swing");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container c = frame.getContentPane(); c.setLayout(new GridLayout(3,2)); c.add(montarPainelLabels()); c.add(montarPainelCaixas()); c.add(montarPainelAreas()); c.add(montarPainelBotoes()); c.add(montarPainelListaComboBox()); c.add(montarPainelCheckRadio()); frame.setSize(800,400); frame.setVisible(true); } Exemplo5.java Os métodos montarPainelXxxx retornam um painel, que será incluído na área de conteúdo do frame.

(18)

private JPanel montarPainelLabels() {

JPanel p = new JPanel();

p.setBackground(Color.white);

JLabel lab1 =

new JLabel("Label contendo apenas texto (posicione o mouse)"); lab1.setToolTipText("Sou um JLabel");

UIManager.put("ToolTip.background", new Color(255,255,213)); Icon micro = new ImageIcon("micro.gif");

JLabel lab2 =

new JLabel("Aqui, o label contém texto azul com um ícone à esquerda", micro, SwingConstants.LEFT);

lab2.setForeground(Color.blue); JLabel lab3 = new JLabel();

lab3.setText("Ícone com texto embaixo"); lab3.setIcon(micro); lab3.setHorizontalTextPosition(SwingConstants.CENTER); lab3.setVerticalTextPosition(SwingConstants.BOTTOM); p.add(lab1); p.add(lab2); p.add(lab3);

O método setToolTipText especifica a

dica exibida quando o usuário posiciona

o mouse sobre o componente GUI. A classe UIManager permite alterar a cor de fundo da dica, de azul (o padrão) para uma cor qualquer.

A classe ImageIcon aceita dois formatos de imagem: GIF (Graphics Interchange Format) e JPEG ou JPG (Joint Photographic Experts Group)

(19)

private JPanel montarPainelCaixas() {

JPanel p = new JPanel();

JTextField tf1 = new JTextField(10);

JTextField tf2 = new JTextField("Texto não editável", 30); tf2.setEditable(false);

JPasswordField pf = new JPasswordField("Uma senha"); p.add(tf1);

p.add(tf2); p.add(pf); return p; }

Mesmo um campo não editável pode ter um tratador de evento.

(20)

private JPanel montarPainelAreas() {

JPanel p = new JPanel();

String s = "Selecione algum texto daqui " +

"e clique no botão Copia.\nO texto selecionado " + "será copiado na área da direita.";

JTextArea areaEsq = new JTextArea(s,5,10); JTextArea areaDir = new JTextArea(5,10); areaEsq.setWrapStyleWord(true);

areaDir.setEditable(false);

JButton copia = new JButton("Copia >"); p.add(new JScrollPane(areaEsq));

p.add(copia);

p.add(new JScrollPane(areaDir)); return p;

}

A classe JTextArea não fornece barras de

rolagem, que precisam portanto ser anexadas. A classe JScrollPane fornece tanto rolagem vertical quanto horizontal. Note que para incluir uma barra de rolagem a um componente, este componente deve ser passado como parâmetro do construtor de

ScrollPane.

Constantes da classe JScrollPane:

VERTICAL_SCROLLBAR_ALWAYS, HORIZONTAL_SCROLLBAR_ALWAYS,

VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED,

Para fornecer a funcionalidade de mudança automática de linha para um JTextArea, invoque o método

(21)

private JPanel montarPainelBotoes() {

JPanel p = new JPanel();

p.setBackground(Color.white);

JButton b1 = new JButton("Um botão bem simples");

Icon img1 = new ImageIcon("micro.gif"); Icon img2 = new ImageIcon("borrao.gif");

JButton b2 = new JButton("Botão com imagem (passe o mouse)",img1); b2.setRolloverIcon(img2);

p.add(b1); p.add(b2); return p; }

Um botão pode incluir uma imagem e uma imagem rollover (exibida quando o mouse é posicionado sobre o botão).

(22)

private JPanel montarPainelListaComboBox() {

JPanel p = new JPanel();

p.setBackground(Color.white);

String itens[] = {"Amarelo","Azul","Branco","Cinza"};

Color cores[] = {Color.yellow,Color.blue,Color.white,Color.lightGray}; JList lista = new JList(itens);

lista.setVisibleRowCount(3);

lista.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); String nomes[] = {"borrao.gif","cadeado.gif","engrenagem.gif",

"escreve.gif","micro.gif","pasta.gif","rede.gif","servidor.gif"}; ImageIcon imagens[] = new ImageIcon[nomes.length];

for (int i = 0; i < nomes.length; i++) {

imagens[i] = new ImageIcon(nomes[i]); }

JComboBox combo = new JComboBox(nomes); combo.setMaximumRowCount(3);

JLabel mostra = new JLabel(imagens[0]); p.add(new JScrollPane(lista));

p.add(combo); p.add(mostra); return p;

Em uma lista, pode-se selecionar

apenas um item (SINGLE_SELECTION) ou, pressionando Ctrl, vários itens (MULTIPLE_INTERVAL_SELECTION).

O método setMaximumRowCount estabelece o número máximo de itens exibidos pelo ComboBox. Note que, para o caso acima, como o ComboBox acima possui 8 itens, uma barra de rolagem será fornecida automaticamente pelo objeto ComboBox. Note que isso não ocorre automaticamente no caso de listas.

(23)

private JPanel montarPainelCheckRadio() {

JPanel p = new JPanel();

JCheckBox cb1 = new JCheckBox("Negrito",false); JCheckBox cb2 = new JCheckBox("Itálico",false); JRadioButton rb1 = new JRadioButton("Nada",false); JRadioButton rb2 = new JRadioButton("Negrito",false); JRadioButton rb3 = new JRadioButton("Itálico",false); JRadioButton rb4 = new JRadioButton("Ambos",false); ButtonGroup bg = new ButtonGroup();

bg.add(rb1); bg.add(rb2); bg.add(rb3); bg.add(rb4);

JPanel grupo = new JPanel(); grupo.add(rb1); grupo.add(rb2); grupo.add(rb3); grupo.add(rb4); p.add(cb1); p.add(cb2); p.add(grupo); return p; }

Note que os botões de rádio precisam ser agrupados para se tornarem

mutuamente exclusivos. Um objeto

ButtonGroup não é um componente

GUI e portanto, não pode ser

acrescentado a um container.

Caixas de seleção (checkbox) e botões de rádio (radiobutton) são semelhantes no sentido de que possuem apenas dois estados: selecionado (SELECTED) ou

(24)

public static void main(String[] args) { Exemplo5 janela = new Exemplo5();

janela.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e)

{

System.exit(0); }});

} }

(25)

• 

Vamos implementar tratamento para os seguintes eventos:

• 

O clique no botão com imagem deve exibir os conteúdos das caixas (de

texto e de senha);

• 

O clique no botão Copia deve copiar o texto selecionado na área da

esquerda para a área da direita;

• 

A seleção de um item da lista deve alterar a cor de fundo do painel;

• 

A seleção de um item do ComboBox deve exibir a imagem

correspondente a este item;

• 

A escolha de um dos botões de rádio deve deixar as caixas de

verificação em um estado consistente.

• 

Vamos imaginar que a própria classe Exemplo5 irá tratar os eventos. Para

isso, a classe deverá implementar as seguintes interfaces:

• 

ActionListener: método actionPerformed

• 

ItemListener: método itemStateChanged

• 

ListSelectionListener: método valueChanged

• 

Exercício

: Incluir na classe Exemplo5 os

ouvidores

de eventos necessários e

identificar todos os objetos que deverão ser declarados como

atributos

da

classe.

(26)

// Tratadores de eventos

public void actionPerformed(ActionEvent e) {

if (e.getSource() == b2) {

JOptionPane.showMessageDialog(null,

"Caixa de texto contém: " + tf1.getText() +

"\nCaixa de senha contém: " + String.copyValueOf(pf.getPassword())); } if (e.getSource() == copia) { areaDir.setText(areaEsq.getSelectedText()); } }

public void valueChanged(ListSelectionEvent e) { if (e.getSource() == lista) { pcor.setBackground(cores[lista.getSelectedIndex()]); } }

(27)

public void itemStateChanged(ItemEvent e) { if (e.getSource() == combo) { mostra.setIcon(imagens[combo.getSelectedIndex()]); } if (e.getSource() == rb1) { cb1.setSelected(false); cb2.setSelected(false); } if (e.getSource() == rb2) { cb1.setSelected(true); cb2.setSelected(false); } if (e.getSource() == rb3) { cb1.setSelected(false); cb2.setSelected(true); } if (e.getSource() == rb4) { cb1.setSelected(true); cb2.setSelected(true); } }

(28)

Exercícios

1. 

Implementar as funcionalidades da GUI

Calculadora

da aula passada.

2. 

Implementar as funcionalidades das aplicações a seguir:

O usuário deverá fornecer os valores do espaço inicial, velocidade inicial e aceleração nas caixas

correspondentes.

O valor de tempo deverá ser gerado aleatoriamente como um inteiro do intervalo [1, 20] quando o usuário clicar no botão Gerar Tempo. O valor gerado deverá ser escrito na caixa correspondente no painel inferior. Use o método Math.random(), que gera um valor aleatório (do tipo double) no intervalo [0.0, 1.0).

(29)

Para o desenho do gráfico, utilize a função g.fillOval(x, y, 3, 3), onde:

g é o contexto gráfico do painel p, obtido pela instrução: Graphics g = p.getGraphics(); x é um valor inteiro que deve variar de 0 a p.getWidth() de 1 em 1;

y é um valor inteiro calculado por:

O botão Limpa deverá limpar as caixas de texto e o painel que contém o gráfico. Para limpar um painel p basta pintar o painel com sua cor de fundo, com os métodos:

g.setColor(Color.white);

g.fillRect(0, 0, p.getWidth(), p.getHeight()); onde g é o contexto gráfico do painel p.

Referências

Documentos relacionados

2 do CFE (...) estabelece a exigência de experiência de magistério para as mencionadas habilitações (...). Não nos parece, entretanto, que tal exigência possa ser feita ao

Convencionam as partes que, exclusivamente para os empregados que mantêm contrato de trabalho com a mesma empresa ou, empresa do mesmo grupo econômico há mais de 10 (dez) anos e

Assim, a casa favorece as relações e a convivência entre (1) gerações de uma mesma família, entre (2) pessoas de famílias diferentes e que são afins na casa em que escolheram

§ 4º Nos Processos Administrativos Disciplinares Demissionários, quando o acusado não constituir ou indicar defensor, a autoridade processante solicitará à autoridade

Considerações Preliminares: O objeto do presente certame é a formação de “Registro de Preços para futura e eventual aquisição de dietas de sistema fechado(industrializada),

Inscrições na Biblioteca Municipal de Ourém ou através do n.º de tel. Organização: Município de Ourém, OurémViva e grupos de teatro de associações e escolas do

Cortesia da Galeria Barbara Gladstone, Nova Iorque.. (©Photo

preta ou azul. Tenha muito cuidado com o cartão de respostas, pois o mesmo não poderá ser substituído. Somente uma corresponde adequadamente ao quesito proposto. Você só deve