Monday, January 25, 2010

Composite Event Handler Registrations in GWT

In my previous entry, I wrote up a class for displaying Input Prompts in GWT. As I started to fold that code into my project, I realized that I didn't expose the handler registrations, which would make it impossible to remove the event handlers if and when the text fields for which input prompts were displayed were created and removed during the lifecycle of the application.

Because the Input Prompt registers handlers for both Blur and Focus, there are two registrations. It's not easy to return two values from a single method, and frankly, I don't think a class using InputPrompt should have to know or care what events it's employing in great detail. As a result, I've created a composite event handler registration to return:


package com.codiform.gwt.event;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.event.shared.HandlerRegistration;

public class CompositeHandlerRegistration implements HandlerRegistration {

private List registrations;

public CompositeHandlerRegistration() {
registrations = new ArrayList();
}

void add( HandlerRegistration registration ) {
if( registration instanceof CompositeHandlerRegistration ) {
CompositeHandlerRegistration composite = (CompositeHandlerRegistration) registration;
registrations.addAll( composite.getRegistrations() );
composite.clear();
} else {
registrations.add( registration );
}
}

private List getRegistrations() {
return registrations;
}

public void removeHandler() {
if ( registrations.size() > 0 ) {
for ( HandlerRegistration item : registrations ) {
item.removeHandler();
}
clear();
} else {
throw new IllegalStateException( "Composite handler registration is currently empty, and cannot remove handlers." );
}
}

private void clear() {
registrations.clear();
}

}


If a composite handler registration is passed to another composite handler registration, I flatten them; this might be unnecessary. In the spirit of YAGNI, I won't be at all unhappy if you decide you don't need that capability. I also decided I preferred to clear my local references to any inner handler registrations as soon as they've been removed, rather than hanging on to them indefinitely.

All in all, this is pretty simple GWT code, but seemed worth following up on the previous entry to talk about the need for handler registrations.

No comments: