Ici, le pattern utilisé est un peu plus complet, notamment par l'ajout d'une clé dans chaque Handle
permettant de trouver simplement l'EventHandler
correspondant.
Liste des différents types d'événements.
- EnumEventType.java
package reactor; public enum EnumEventType { MessageEvent, ClickEvent }
Classe Handle
qui contient l'événement et sa clé de reconnaissance.
- Handle.java
package reactor; import java.util.EventObject; public class Handle { private String key; private EventObject event; public EventObject getEvent() { return event; } public String getKey() { return key; } public void setKey(String key) { this.key = key; } public void setEvent(EventObject event) { this.event = event; } }
Interface que doivent implémenter chaque traitement d'événement.
- EventHandler.java
package reactor; public interface EventHandler { public void handleEvent(); public Handle getHandle(); public void setHandle(Handle h); }
C'est la classe qui s'occupe de faire la correspondance entre l'événement et le traitement.
- SynchronousEventDemultplexer.java
package reactor; import java.util.ArrayList; public class SynchronousEventDemultplexer { public SynchronousEventDemultplexer() { super(); } public EventHandler select(Handle h, ArrayList<EventHandler> list) { if (h == null) { return null; } for (EventHandler eventHandler : list) { if (eventHandler.getHandle().getKey().equals(h.getKey())) { eventHandler.setHandle(h); return eventHandler; } } return null; } }
Le Reactor
reçoit les événements, les stockent puis les traitent.
- Reactor.java
package reactor; import java.util.ArrayList; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; public class Reactor extends Thread { private Queue<Handle> receivedHandle; private SynchronousEventDemultplexer sync; private ArrayList<EventHandler> listEventHandler; public Reactor(SynchronousEventDemultplexer sync) { super(); receivedHandle = new ConcurrentLinkedQueue<Handle>(); listEventHandler = new ArrayList<EventHandler>(); this.sync = sync; } public void registerHandler(EventHandler e) { listEventHandler.add(e); } public void removeHandler(EventHandler e) { listEventHandler.remove(e); } public void startHandleEvents() { System.out.println("Class = Reactor, Methode = startHandleEvents :: Attente événements..."); EventHandler retour = sync.select(receivedHandle.poll(), listEventHandler); if (retour != null) { retour.handleEvent(); } } public void receive(Handle h) { System.out.println("Class = Reactor, Methode = receive :: réception d'un événement !!! " + h.getEvent().getSource()); receivedHandle.add(h); } public void run() { while (true) { startHandleEvents(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
Environnement pour simuler des événements à transmettre au Reactor
.
- Environment.java
package reactor; import java.util.EventObject; public class Environment extends Thread { Reactor reactor; public Environment(Reactor reactor) { this.reactor = reactor; } @Override public synchronized void run() { int compteurClickEvent = 1; int compteurMessageEvent = 1; for (int i = 0; i < 5; i++) { synchronized (reactor) { Handle handleClick = new Handle(); handleClick.setEvent(new EventObject(EnumEventType.ClickEvent + "_" + compteurClickEvent)); handleClick.setKey(EnumEventType.ClickEvent.toString()); reactor.receive(handleClick); compteurClickEvent++; } synchronized (reactor) { Handle handleMaessage = new Handle(); handleMaessage.setEvent(new EventObject(EnumEventType.MessageEvent + "_" + compteurMessageEvent)); handleMaessage.setKey(EnumEventType.MessageEvent.toString()); reactor.receive(handleMaessage); compteurMessageEvent++; } try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
Une première implémentation possible d'un traitement d'événement.
- MessageHandler.java
package reactor; public class MessageHandler implements EventHandler { private Handle handle; @Override public void handleEvent() { System.out.println("Class = reactor.MessageHandler, Methode = handleEvent :: traitement evenement " + handle.getEvent().getSource()); } @Override public Handle getHandle() { return handle; } @Override public void setHandle(Handle h) { handle = h; } }
Une deuxième implémentation possible d'un traitement d'événement.
- ClickHandler.java
package reactor; public class ClickHandler implements EventHandler { private Handle handle; @Override public void handleEvent() { System.out.println("Class = reactor.ClickHandler, Methode = handleEvent :: traitement evenement " + handle.getEvent().getSource()); } @Override public Handle getHandle() { return handle; } @Override public void setHandle(Handle h) { handle = h; } }
Le programme principal qui lie tout le monde entre eux.
- Main.java
package reactor; public class Main { public static void main(String[] args) { try { Reactor reactor = new Reactor(new SynchronousEventDemultplexer()); EventHandler messageHandler = new MessageHandler(); messageHandler.setHandle(new Handle()); messageHandler.getHandle().setKey(EnumEventType.MessageEvent.toString()); reactor.registerHandler(messageHandler); EventHandler clickHandler = new ClickHandler(); clickHandler.setHandle(new Handle()); clickHandler.getHandle().setKey(EnumEventType.ClickEvent.toString()); reactor.registerHandler(clickHandler); Thread threadReactor = new Thread(reactor); Environment environment = new Environment(reactor); threadReactor.start(); environment.start(); threadReactor.join(); environment.join(); } catch (InterruptedException e) { e.printStackTrace(); } } }