[java-gnome-hackers] Implementation change to GTK classes
Brought to you by:
afcowie
From: Tom B. <Tom...@Su...> - 2002-11-26 18:43:21
|
Libglade needs to map signals to event listener classes on a per-class basis. To avoid developing a separate table for these mappings (which makes maintenance harder), I have augmented the information already in the classes which handle events (if you can think of a better way, please let me know). Note: this change doesn't affect any public API, nor how event handling is actually managed. Currently, classes which handle events all have a protected method called initializeEventHandlers(). Each class implements this as: protected void initializeEventHandlers() { super.initializeEventHandlers(); // optional addEventHandler(<signal>, <handler>, this); addEventHandler(<signal>, <handler>, this); // etc. } Although no map object is actually used, these addEventHandler statements provide the mapping I need to extend. This is done by creating a private static EventMap instance and storing this information plus the event listener class in it. The above code then looks like: protected void initializeEventHandlers() { evtMap.initialize(this); } private static EventMap evtMap = new EventMap(); static { evtMap.addEvent(<signal>, <handler>, <listener_class>); evtMap.addEvent(<signal>, <handler>, <listener_class>); // etc. } public static String getListenerClass(String signal) { return evtMap.getListenerClass(signal); } The EventMap class looks like this: /*package-private*/class EventMap { private List events = new ArrayList(); private class Entry { String signal; String method; String listenerClass; Entry(String s, String m, String l) { signal = s; method = m; listenerClass = l; } } void addEvent(String signal, String method, String listenerClass) { events.add(new Entry(signal, method, listenerClass)); } /** * Connect all event handlers to this event source. */ void initialize(GObject source) { Iterator i = events.iterator(); while (i.hasNext()) { Entry e = (Entry)i.next(); /* All GTK addEventHandler calls specify source twice * (the object being invoked and as a cbrev parameter). * This should probably be eliminated to for performance. */ source.addEventHandler(e.signal, e.method, source); } } /** * Return the name of the event listener class for a given signal. */ String getListenerClass(String signal) { Iterator i = events.iterator(); while (i.hasNext()) { Entry e = (Entry)i.next(); if (e.signal.equals(signal)) return e.listenerClass; } return null; } } Yes, it is called a Map but uses a List, but that doesn't matter because the List and its interface is completely private. If this impacts performance in any way, it can be changed later to be an array. I chose to make initialization faster than listener lookup, since there are going to be a lot more widget creations than libglade lookups. If no one complains in a day or so, I'll check these in. Tom |