POO Tratamento de Eventos Eventos são a forma utilizada por Java para adicionar interatividade em interfaces gráficas. Cada vez que o usuário pressionar um botão, digitar um caracter ou movimentar o mouse, por exemplo, ocorre um evento. Sempre que o usuário utiliza o mouse, o teclado ou outro dispositivo de entrada qualquer, o sistema operacional se encarrega de converter essas ações em eventos. Para cada evento que o sistema operacional é capaz de gerar, a aplicação deve prever um tratamento correspondente (“o que deve acontecer em resposta”). Em Java a ação resposta padrão para qualquer evento é “não fazer nada”. Para se ter uma ação em resposta, é necessário definir qual ou quais os componentes que serão encarregados de monitorar determinado evento, reagindo ao mesmo quando este ocorrer. Dizemos que um componente capaz de perceber um evento é um componente capaz de “escutá-lo” ou “captá-lo”. Em Java, dizemos que para um componente ser capaz de perceber um evento (e tratá-lo) é necessário associar um “listener” (algo como um “ouvinte”) ao componente. Existem 4 componentes envolvidos no processo de tratamento de eventos: – Origem do evento: é um componente onde o evento é gerado. • Ex.: um evento de clique do mouse pode ser originado de um botão – Evento: é um objeto que representa o evento gerado. – Listener ou Receptor de Evento: é um objeto responsável por “ouvir” ou “captar” a ocorrência do evento. – Handler: é um método do Listener responsável por executar as ações decorrentes do evento. OK Origem do Evento Notificação do Evento contendo o objeto que representa o Evento. Listener Handler Como isso acontece? – Em primeiro lugar • O listener tem que se registrar no objeto origem do evento, informando que tipo de evento ele está interessado em receber. – Quando um evento ocorre • O listener é notificado que o evento ocorreu • O objeto origem notifica o listener através da execução de um método específico, o qual recebe como parâmetro o objeto evento. – Quando o listener recebe a notificação • Ele executa o método handler apropriado. Como implementar um listener? – Vimos que o objeto origem de um evento notifica o listener através da execução de um método específico. • Cada tipo de evento possui métodos específicos para o seu tratamento. – Que métodos são esses? Como a minha classe listener sabe quais métodos ela deve implementar? – Utilizamos o conceito de interface. • Não confundir com interface gráfica, interface de usuário...! – Dessa forma, um listener deve implementar um certa interface. • Esta interface define os métodos que serão chamados quando os eventos ocorrerem. – Ex.: • O evento que ocorre quando um botão é clicado é o evento (objeto) ActionEvent. • Todos os listeners que estão registrados para um botão, que esperam receber a notificação de um clique do botão, devem implementar o método actionPerformed(), que será chamado pelo botão quando for clicado. • Este método está definido na interface ActionListener, logo o listener deverá implementar esta interface. public interface ActionListener{ void actionPerformed(ActionEvent e ); } public class AcoesBotao implements ActionListener{ public void actionPerfomed(ActionEvent e){ //Aqui vem o código que é executado //quando o botão for pressionado. } } Como registrar um listener? – Os listeners devem ser registrados com o objeto que gera o evento. • Ou seja, devemos indicar quem implementa as ações para os eventos daquele componente. – Cada tipo de evento tem um correspondente método para adicionar um listener. – Ex.: para ActionEvent, o método é addActionListener(). JButton ok = new JButton (“Ok”); AcoesBotao botaoListener = new AcoesBotao(); ok.addActionListener(botaoListener); Exemplo import javax.swing.*; import java.awt.event.*; //Para utilizar eventos public class TestaEventos extends JFrame implements ActionListener { //Esta classe é um listener de eventos de ação JButton but; JLabel texto; JPanel painel; int cont; public TestaEventos() { //Cria um frame com os componentes super("TestaEventos"); cont = 0; //Contador do número de cliques no botão but = new JButton("Clique aqui"); texto = new JLabel("Total de cliques: 0"); painel = new JPanel(); painel.setLayout(new BoxLayout(painel,BoxLayout.Y_AXIS)); painel.add(but); painel.add(texto); //Registra o listener para ações no botão but.addActionListener(this); // A própria classe implementa as ações this.getContentPane().add(painel); } //Método exigido pela interface ActionListener public void actionPerformed(ActionEvent e) { cont++; texto.setText("Total de cliques: "+cont); } public static void main(String[] args){ JFrame janela = new TestaEventos(); janela.setDefaultCloseOperation( WindowConstants.DISPOSE_ON_CLOSE); janela.show(); } } Classe ActionEvent: – Método getSource() • Retorna uma referência ao objeto que gerou o evento. – Método getActionCommand() • Retorna informações sobre o objeto origem do evento, por exemplo, se chamado em um botão, por default retornará o string do texto do botão. • Retorna a string relacionada ao componente que foi atribuída pelo método setActionCommand(string). – Podemos usar esses métodos para gerenciar eventos de mais do que um componente, com o mesmo listener. Exemplo2: import javax.swing.*; import java.awt.event.*; public class TestaEventos2 extends JFrame implements ActionListener { JButton but1; JButton but2; JPanel painel; public TestaEventos2() { ... but1.addActionListener(this); but2.addActionListener(this); ... } public void actionPerformed(ActionEvent e) { if (e.getSource() == but1) setTitle("Botão 1"); else if (e.getSource() == but2) setTitle("Botão 2"); repaint(); //Redesenha a janela após mudanças } ... } import javax.swing.*; import java.awt.event.*; public class TestaEventos2 extends JFrame implements ActionListener { JButton but1; JButton but2; JPanel painel; public TestaEventos2() { ... but1.addActionListener(this); but2.addActionListener(this); ... } public void actionPerformed(ActionEvent e) { if (“Botão 1”.equals(e.getActionCommand())) setTitle("Botão 1"); else if (“Botão 2”.equals(e.getActionCommand())) setTitle("Botão 2"); repaint(); //Redesenha a janela após mudanças } ... } Exemplos de eventos, listeners e métodos: ActionEvent FocusEvent ActionListener FocusListener ItemEvent KeyEvent ItemListener KeyListener MouseEvent MouseListener TextEvent TextListener actionPerformed() focusGained() focusLost() itemStateChanged() keyPressed() keyReleased() keyTyped() mouseClicked() mouseEntered() mouseExited() mousePressed() mouseReleased() textValueChanged() Eventos gerados por componentes (resumo): JButton ActionEvent botão “clicado” JCheckbox ItemEvent item selecionado/desmarcado JCheckboxMenuItem ItemEvent idem JChoice ItemEvent idem JList ActionEvent duplo-clique sobre o item ItemEvent item selecionado/desmarcado JMenuItem ActionEvent item selecionado/desmarcado JScrollbar AdjustmentEvent scrollbar movimentada JTextComponent TextEvent texto alterado JTextField ActionEvent término da edição do texto Classes Adaptadoras: – Algumas das interfaces para a construção dos listeners possuem mais de um método. – Ao implementar o listener, precisamos definir todos os métodos, mesmo que só estejamos interessados só em um tipo de evento. – Ex.: • MouseListener contém 5 métodos, e devemos implementar todos eles, mesmo que só utilizemos o método mousePressed(). – Para facilitar a implementação de listeners, Java fornece um conjunto de classes adaptadoras. – As classes adaptadoras (adapter) são utilizadas para que o usuário tenha que implementar apenas os métodos que ira utilizar. – Estas classes já implementam a interface de interesse, mas com todos os métodos com corpo vazio (sem código). – Para programar o listener, herdamos da classe adapter e sobrescrevemos apenas os métodos que desejamos utilizar! – Algumas classes adaptadoras: • • • • • • • • ComponentAdapter - ComponentListener ContainerAdapter - ContainerListener FocusAdapter - FocusListener KeyAdapter - KeyListener MouseAdapter - MouseListener MouseMotionAdapter - MouseMotionListener WindowAdapter - WindowListener ActionListener não possui classe adaptadora pois só possui um método. – Ex.: queremos um listener para o MouseListener. import java.awt.event.*; public class TestaEventos4Adaptador extends MouseAdapter{ public void mousePressed(MouseEvent e){ System.out.println("Botao pressionado"); } public void mouseReleased(MouseEvent e){ System.out.println("Botao liberado"); } } Classes Anônimas Internas: – Uma vez criada a classe que implementa a interface ou define uma subclasse de uma classe adaptadora, esta precisa ser instanciada e o objeto registrado como listener. – É possível implementar e registrar o listener em um passo só. – Basta implementar o listener como uma classe anônima (sem nome) interna (uma classe definida dentro de outra classe. – Observe que se forem utilizadas classes internas anônimas, não será possível tratar múltiplos componentes. – Deveremos implementar uma classe anônima para cada componente. – Não aconselhável para código de tratamento que seja muito longo. Exemplo: but.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { cont++; texto.setText("Total de cliques: "+cont); } }); janela.addWindowListener( //código para executar quando a janela é fechada new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); // fecha e sai do programa } }); Exemplo Menu: JMenu mFile = new JMenu("File"); JMenuItem miOpen = new JMenuItem("Open"); miOpen.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { campo.setText(e.getActionCommand()); } }); mFile.add(miOpen); – Algumas interfaces (java.awt.event.*): • ActionListener - eventos de ação, que são gerados por um usuário agindo sobre um componente, como um clique em um botão. • FocusListener - eventos de foco de teclado, que são gerados quando um componente, como um campo de texto, ganha ou perde o foco. • ItemListener - eventos de item, que são gerados quando um item, como uma caixa de seleção, foi alterado. • KeyListener - eventos de teclado, que ocorrem quando uma tecla é pressionada. • MouseListener - eventos de mouse, que são gerados por cliques do mouse, um mouse entrando ou deixando uma área de um componente. • MouseMotionListener - eventos de movimento de mouse, usados para controlar a movimentação do mouse sobre um componente. • WindowListener - eventos de janela, que são gerados por uma janela ao ser maximizada, minimizada, movida ou fechada. WindowListener: – windowOpened(WindowEvent e) - Chamado a primeira vez que a janela é aberta. – windowClosing(WindowEvent e) - Chamado quando o ícone de fecha janela é selecionado. – windowClosed(WindowEvent e) - Chamado quando do fechamento de uma janela. – windowActivated(WindowEvent e) - Chamado quando uma janela é ativada (clicando sobre a mesma, por exemplo). – windowDeactivated(WindowEvent e) - Chamado quando uma janela é desativada (clicando sobre uma outra janela, por exemplo). – windowIconified(WindowEvent e) - Chamado quando uma janela é minimizada. – windowDeiconified(WindowEvent e) - Chamado quando uma janela é restaurada a partir de um ícone. ActionListener: – actionPerformed - Chamado quando uma ação ocorre. MouseListener: – mouseClicked(MouseEvent e) - Chamado quando o botão do mouse é clicado (e solto) sobre um componente. – mousePressed(MouseEvent e) - Chamado quando o botão do mouse é clicado sobre um componente. – mouseReleased(MouseEvent e) - Chamado quando o botão do mouse é solto sobre um componente. – mouseEntered(MouseEvent e) - Chamado quando o mouse “entra” na área de um componente. – mouseExited(MouseEvent e) - Chamado quando o mouse deixa a área de um componente. MouseMotionListener: – mouseMoved(MouseEvent e) - Chamado quando o mouse se movimenta com um componente (drag) – mouseDragged(MouseEvent e) - Chamado quando o mouse se movimenta com um componente (drag) enquanto o botão do mouse está pressionado KeyListener: – keyTyped(KeyEvent e) - Chamado quando uma tecla do teclado é pressionada e solta – keyPressed(KeyEvent e) - Chamado quando uma tecla do teclado é pressionada – keyReleased(KeyEvent e) - Chamado quando uma tecla do teclado é solta Exercícios 1) Escreva um programa em Java que implemente uma calculadora simples (com operações de adição, subtração e multiplicação) para números inteiros.