Elegant Event Handling in Java

Event handling is something very common, especially in desktop application. So how does you’re event handling code look like? Something like this?

Handling Events

Handling Events

Of course you don’t want to have this kind of code in every class. Therefore you create a special event-handling class. That class manages all registered events and can fire the event to all listeners.

But how do you do that when there are multiple event types? Then the types are represented by different interfaces with different method signatures. You really want to handle all these events with the same event-handler class. Let’s take a look at my solution. Here’s an example where I handle different events:

Could not embed GitHub Gist 955775: API rate limit exceeded for 208.113.160.6. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)

As you see I use the EventListeners for representing an event. To register events I just call the add-method on it. Now to the real cool part: To fire the event, I get the invoker and just call the method I want to. That method can by any method of the event-handler interface. That makes it very flexible; I can use this for any kind of event-handler interface! I haven’t seen a more elegant way to handle events in Java yet.

How is this implemented? The internally implements the usual add/remove and invoke-logic, but with a twist. It uses the generic argument for handling everything. For the invoke-part it creates a dynamic proxy object of the generic argument. That is the object which is returned by the invoker()-method. When you call any method on that object, it will delegate that invoke to all listeners. (Yes, for the .NET guys, that somewhat a reimplementation of a multi-cast delegate).

Could not embed GitHub Gist 955775: API rate limit exceeded for 208.113.160.6. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)

For my implementation I just used a Java proxy instance. Of course the implementation adds overhead to the call and only works with interfaces. For a more advanced implementation you could use a code generator library. That probably would speed up things and also allow classes as event-handlers.

That’s it. I handle my event this way in Java. If you found an event more elegant way, let me know.

P.S. I’m wondering if I should start a small Java library which contains all these kinds of small tricks I’m posting here. Hmm…

Tagged on: ,

4 thoughts on “Elegant Event Handling in Java

  1. SirYes

    Yes, that’s very elegant. I was implementing some Java class, when I went “hey, I need to handle events”. I know how to do this in Delphi and .NET/C#, and I know how to use Swing events (even if I don’t really like their approach).

    So I’ve looked into JButton: http://www.docjar.com/html/api/javax/swing/JButton.java.html searching for “actionPerformed()” method, but no luck.
    Then I went to AbstractButton: http://www.docjar.com/html/api/javax/swing/AbstractButton.java.html and found “fireActionPerformed()” – which looked pretty ugly.
    I even went to EventListenerList: http://www.docjar.com/html/api/javax/swing/event/EventListenerList.java.html – to confirm my suspicion, that there is a mess in Java regarding events. And it is inherited from old, pre-generics, Swing design.

    I knew there must have been some better way.

    I’ve found: http://www.javaworld.com/javaworld/javaqa/2002-03/01-qa-0315-happyevent.html – funny, but not so useful.
    Then this: http://castever.wordpress.com/2008/07/31/how-to-create-your-own-events-in-java/ – little better, and with synchronized methods (nice bonus).
    This one looked promising: http://www.jillesvangurp.com/2005/10/26/late-to-generics/ – quite promising, but I kept on looking.

    But your code is the best so far. I’m going to test it and will probably use it in my internal, little project.

    Thanks a lot!

  2. gamlerhart Post author

    Thanks…

    Just remind you that this adds some overhead for the dispatch with the proxy. However for most applications that should be a issue.

    Also you maybe don’t like the ‘remove’ via disposable and prefer a remove method. Of course you can change that to your liking.

  3. Mark

    Solid way of handling events in Java! Did you ran into any problems were you’d like to handle events with return values?

    I.e.:

    public interface ComplexEventHandler {
    boolean ohMyGod(String name,String otherName, int test);
    }

    return complexEvent.invoker().ohMyGod("complex","more complex",42);

    This doesn’t seem to work…

  4. gamlerhart Post author

    No, this doesn’t work. That would require some more work and though. Especially how to deal with all the return values. Mabye somehow it could return a list of the return values. Or at the last result.

    For returning a list the API whould need to be have some extra bit, so that the type is suddenly a list. Like:

    return withResultList(complexEvent.invoker().ohMyGod(“complex”,”more complex”,42));

    More though needed.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>