Hello,

We have implemented an annotation based solution to avoid the type safety / instanceof problem with the events. Instead of

@Override
public void onEvent(IEvent<?> event) {
  Object payload = event.getPayload();
  if (payload instanceof FirstEvent) {
    payload.doSomething();
  } else if (payload instanceof SecondEvent) {
    payload.doSomethingElse();
  }
}

you can do

@OnEvent
public void onEvent(FirstEvent event) {
  event.doSomething();
}

@OnEvent
public void onEvent(SecondEvent event) {
  event.doSomethingElse();
}

The implementation is available here:

  https://github.com/NitorCreations/wicket

To use this event dispatcher, you need to have this in your application initialization:

AnnotationEventDispatcher dispatcher = new AnnotationEventDispatcher();
getComponentInstantiationListeners().add(dispatcher);
getFrameworkSettings().add(dispatcher);

To minimize the performance impact, the annotated methods are scanned only once per component class (when the first component of that class is instantiated). Also the annotated methods for the component class to be called for a certain event payload type are resolved only once (when the first event of that type is dispatched for the component type).

To enhance this further, we have been thinking about making the current event handling optional to avoid calling the empty Component.onEvent for each and every event. However, there is currently no support for annotated methods in Behaviors etc., only in Components.

Best Regards,

Edvard

p.s. This works in Wicket 6 as well.

On 01.06.2013 06:54, Ernesto Reinaldo Barreiro wrote:
Hi Martin,

Thank you very much for your answer and apologies for my late reply.

On Thu, May 30, 2013 at 11:32 AM, Martin Grigorov <[email protected]>wrote:

Hi Ernesto,

With the current API I'd do it :

@Override
public void onEvent(IEvent<?> event) {
   Object payload = event.getPayload();
   if (payload instanceof FirstEvent) {
      handle((FirstEvent) payload);
   } else if (payload instanceof AnotherEvent) {
      handle((AnotherEvent) payload);
   }
   ...
}

private void handle(FirstEvent) { ... }
private void handle(AnotherEvent) { ... }

It is fairly clean.


That's what I wanted to avoid... I would like "someone" to take care of
this plumbing for me.




With IFrameworkSettings#add(IEventDispatcher) this logic can be generalized
even more.
For example:

@EventCallback  // custom annotation
private void handle(FirstEvent) {...}

i.e. use reflection to find all annotated methods which accept the type of
the event as parameter.

See org.apache.wicket.EventDispatcherTest#dispatchToAnnotatedMethod() in
wicket-core unit tests for a simple implementation.
A more robust impl should cache the results of the reflection
introspections.


  Yes I was aware you can plug you own event delivery machinery.... I think
I will explore the "reflection based approach" either with annotations or
using some convention on methods' names. I'm using events mostly at panel
level. So, it might make much sense to roll my own "EventedPanel" and
inherit form it... than hooking into global settings. I will play with both
and decide which way I go.

Thanks again for your support!

Cheers,

Ernesto Reinaldo Barreiro


--
Edvard Fonsell
[email protected]
+358(0)40 722 7554

Reply via email to