Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@gamlerhart
Created May 4, 2011 18:53
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gamlerhart/955775 to your computer and use it in GitHub Desktop.
Save gamlerhart/955775 to your computer and use it in GitHub Desktop.
EventHandling
public interface ComplexEventHandler {
void ohMyGod(String name,String otherName, int test);
}
public interface Disposable {
/**
* Full cleanup of the component. Afterwards the component is ready to get cleaned by garbage collection.
* This means no references of this component are hold anymore in the application.
*/
public void dispose();
}
public final class EventListeners<T> implements Disposable {
private final Set<T> listeners = new HashSet<T>();
private final T invoker;
public EventListeners(Class classInfo) {
this.invoker = buildInvoker(classInfo);
}
@Override
public void dispose() {
listeners.clear();
}
public Disposable add(final T event) {
listeners.add(event);
return new Disposable() {
@Override
public void dispose() {
removeHandler(event);
}
};
}
public T invoker() {
return invoker;
}
public static <T> EventListeners<T> create(Class classInfo) {
return new EventListeners<T>(classInfo);
}
private void removeHandler(T event) {
listeners.remove(event);
}
private void invokeEventHandling(Method method, Object[] args) {
for (T listener : listeners) {
try {
method.invoke(listener, args);
} catch (Exception e) {
reThrow(e);
}
}
}
private T buildInvoker(Class classInfo) {
return (T) Proxy.newProxyInstance(classInfo.getClassLoader(),
new Class[]{classInfo},
createInvocationHandler());
}
private InvocationHandler createInvocationHandler() {
return new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
invokeEventHandling(method, args);
return null;
}
};
}
}
// 1. Create a 'EventListeners'-instance for handling events
private final EventListeners<NoArgumentEvent> simplerEvents = EventListeners.create(NoArgumentEvent.class);
private final EventListeners<ComplexEventHandler> complexEvent = EventListeners.create(ComplexEventHandler.class);
public void somethingSimpleChanged(){
// 2. I just can get the invoker, and then call the right method on it.
// This works for every kind of interface.
simplerEvents.invoker().eventOccurred();
}
public void somethingComplexChanged(){
complexEvent.invoker().ohMyGod("complex","more complex",42);
}
// Delegate adding events
public Disposable addSimpleEvent(NoArgumentEvent event) {
return simplerEvents.add(event);
}
private final Set<NoArgumentEvent> events= new HashSet<NoArgumentEvent>();
public void somethingChanged(){
for (NoArgumentEvent eventHandler : events) {
eventHandler.eventOccurred();
}
}
public Disposable addSimpleEvent(NoArgumentEvent event) {
return events.add(event);
}
public interface NoArgumentEvent {
public void eventOccurred();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment