Event Listeners and Triggers in Java

There are a lot of mistakes I’ve seen people make when coding event listeners (and more commonly the classes that trigger events) in Java. One of the most common mistakes is:

List listeners = new ArrayList();

So whats the problem here? Well for one thing: ArrayList (like it says in the JavaDoc) is not synchronized, so it’s great for a single-thread environment. However, GUI’s are very often multi-threaded environments (unless you do everything on the EventDispatchThread, which is also a bad idea), so you may end up with a corrupt list of listeners.

Synchronization and threading issues are not massively likely in a GUI environment, but GUI applications are not the only ones with events, the problem can be solved in a few simple ways:

List listeners = new Vector();

or a more modern approach:

List listeners = Collections.synchronizedList(new ArrayList());

There is also the lovely javax.swing.EventListenerList which also happens to be a much more memory efficient solution. Bare in mind that it’s not bound to Swing in any way (other than the package it’s in). ArrayList and Vector both allocate memory for 10 entires when they are first initialized, whats more they grow exponentially in size. This is great if you are working with rapidly growing lists, but event listener lists tend to grow slowly and very seldom. EventListenerList lazy-creates it’s internal list, and so pre-allocates no “real” memory (space for a pointer, thats about it).

My preference for lists of event listeners is the java.util.concurrent.CopyOnWriteArrayList:

List<MouseListener> listeners = new CopyOnWriteArrayList<MouseListener>();

The CopyOnWriteArrayList is expensive to write to (add or remove), but wonderfully memory efficient, and inherently thread-safe. So unlike other List types, when firing an event off, you don’t have to synchronize on the List object, since if a write happens at the same time, the iterator you use points to a different array to the edited one.

MouseEvent e = new MouseEvent(...);
    for(MouseListener l : listeners) {
    l.mousePressed(e);
}

vs.

MouseEvent e = new MouseEvent(...):
synchronized(listeners) {
    for(MouseListener l : listeners) {
        l.mousePressed(e);
    }
}

One last note: When dealing with PropertyChangeListeners and Events (which is probably 60% of all events I work with), be sure to use a java.beans.PropertyChangeSupport to handle things for you.

Netbeans Music Player Released

The Music Player module for Netbeans that I was talking about here has been published in the Netbeans Plugin Portal. It’s early days, but heres a list of features it already includes:

  • A Collection tab that sits in the same space as “Projects”; “Files” and “Runtime”
  • A Play list that occupies a tab with the source editor
    • The play list can be closed without causing the play problems
  •  Plays OGG and MP3 files
  • A player-controls toolbar

Here’s the link:http://plugins.netbeans.org/PluginPortal/faces/PluginDetailPage.jsp?pluginid=3219

Go download and enjoy! I’ll be releasing the source-code as soon as I’ve got a bit more time.

A Music Player for Netbeans

I finally decided to climb into the Netbeans platform (been meaning to do it for ages). I figured there are only really 3 things I want Netbeans to do that it can’t already do:

  1. Play Music while I code
  2. Check; Read and Write Email
  3. Browse the web (properly, not just HTML 3.2)

Since playing music turned out to be the most important for me, I decided that I’d write a music player as my first Netbeans module. I’m basing the entire module heavily on Amarok, since thats by far the best music player I’ve used (and I’ve used plenty). Currently the code has a Collection (of all your music), and a Playlist. It also adds a new menu, titled “Multimedia”.

Heres a screen-shot of the app so far:

nbentertainer.jpg

The Netbeans Platform (once you get your head around a few simple concepts) is a dream to work with. If you haven’t already used it, try coding something simple on it, you’ll almost certainly love it!

Update (18:15):

It’s already at a point that it’s quite usable, I’ll find somewhere to open-source the module in the next day or so, and post a link to it on my blog. It’s now happily playing a Nightwish MP3 in the background for me. It makes life a whole lot easier when you don’t have to leave your IDE to do something like queue a song.