Listener - criando um

Para criar nosso próprio listener, vamos imaginar um telefone. Possui método toca e atende e implementa eventos como tocou e atendido.


Para criar um Listener, primeiro temos que criar uma interface para nosso listener herdando de EventListener

TelefoneListener

 

public interface TelefoneListener extends java.util.EventListener {

 

 void telefoneTocou(TelefoneEvent e);

 void telefoneAtendido(TelefoneEvent e);

}

 


Criaremos também um Event para que possamos saber qual "telefone" está chamando o evento

TelefoneEvent

 

public class TelefoneEvent extends java.util.EventObject {

 

 public TelefoneEvent(Telefone source) {

         super(source);

 }

}

 


Um adapter nos ajuda para caso queiramos implementar apenas um dos métodos do Listener sem precisar deixar os demais vazios

TelefoneAdapter

 

public class TelefoneAdapter implements TelefoneListener {

 

 public void telefoneTocou(TelefoneEvent e) {}

 public void telefoneAtendido(TelefoneEvent e) {}

 

}

 


Agora implementamos o telefone propriamente dito, este terá o método addTelefoneListener

Telefone

 

import java.util.ArrayList;

import java.util.Collection;

 

public class Telefone {

 private Collection <TelefoneListener> telefoneListeners = new ArrayList<TelefoneListener>();

 

 // método de suporte para testar a solução

 public void tocaFone() {

         disparaTelefoneTocou();

 }

 

 // método de suporte para testar a solução

 public void atendeFone() {

         disparaTelefoneAtendido();

 }

 

 public synchronized void addTelefoneListener(TelefoneListener l) {

         if(!telefoneListeners.contains(l)) {

                 telefoneListeners.add(l);

         }

 }

 

 public synchronized void removeTelefoneListener(TelefoneListener l) {

         telefoneListeners.remove(l);

 }

 

 private void disparaTelefoneTocou() {

         Collection <TelefoneListener> tl; 

         synchronized (this) {

                 // Clonar para evitar problemas de sincronização

                 // durante a propagação

                 tl = (Collection)(((ArrayList)telefoneListeners).clone());

         }

         TelefoneEvent evento = new TelefoneEvent(this);                

         for (TelefoneListener t : tl) {

                 t.telefoneTocou(evento);

         }

 }

 

 // disparaTelefoneAtendido() é semelhante a disparaTelefoneTocou()

 // Exercício: Que design pattern poderia ser usado para fatorar o código comum?

 private void disparaTelefoneAtendido() {

         Collection <TelefoneListener> tl; 

         synchronized (this) {

                 tl = (Collection)(((ArrayList)telefoneListeners).clone());

         }

         TelefoneEvent evento = new TelefoneEvent(this);

         for (TelefoneListener t : tl) {

                 t.telefoneAtendido(evento);

         }        

 }

}

 


Para testar, vamos criar 2 classes que utilizam o telefone, sendo que cada uma se utiliza de uma maneira diferente do listener que criamos

SecretariaEletronica

public class SecretariaEletronica implements TelefoneListener {

 

    public void telefoneTocou(TelefoneEvent e) {

        System.out.println("Secretaria escuta o telefone tocando.");

    }

 

    public void telefoneAtendido(TelefoneEvent e) {

        System.out.println("Secretaria sabe que o telefone foi atendido.");

    }

}

 

Pessoa

 

public class Pessoa {

 public void escutaTelefone(Telefone t) {

         t.addTelefoneListener(

                         new TelefoneAdapter() {

                                 public void telefoneTocou(TelefoneEvent e) {

                                         System.out.println("Eu pego!");

                                         ((Telefone)(e.getSource())).atendeFone();

                                 }

                         }

         );

 }

}

 

Teste (main)

 

public class Teste {

 

 public static void main(String[] args) { 

         Telefone fone = new Telefone();

         Pessoa fulano = new Pessoa();

         SecretariaEletronica se = new SecretariaEletronica();

 

         fone.addTelefoneListener(se);

         fulano.escutaTelefone(fone);

 

         fone.tocaFone(); // começa a brincadeira

 }

}

 

Saída

Secretaria escuta o telefone tocando.

Eu pego!

Secretaria sabe que o telefone foi atendido.

 

Saida mais

 

http://www.dsc.ufcg.edu.br/~jacques/cursos/map/html/arqu/observer.htm