Easier Custom Events Handling in Java
In Java, everytime I want to create a new custom event, I usually do it by add 3 methods namely:
addDogEventListener(EventListener listener);
removeDogEventListener(EventListener listener);
dispatchDogEventListener(DogEvent event);
Then now if I want to dispatch another event, say CatEvent, I will have to create all these 3 methods again:
addCatEventListener(EventListener listener);
removeCatEventListener(EventListener listener);
dispatchCatEventListener(CatEvent event);
Then if I want to manage just one kind of CatEvent event, say Meow, I have to copy and paste all these 3 methods again?! Like addCatMeowEventListener();... etc?
And usually, I need to dispatch more than one kind of events. It will be very untidy to have the whole class filled with so many methods to transmit and handle the events. Not only that, these functions have very similar code, like loop through the EventListenerList, add event to the list, etc.
Is this how I should do event dispatching in Java?
Is there a way like I can do it like:
mainApp.addEventListener(CatEvent.MEOW, new EventHandler() { meowHandler(Event e) { });
mainApp.addEventListener(CatEvent.EAT, new EventHandler() { eatHandler(Event e) { });
myCat.addEventListener(DogEvent.BARK, new EventHandler() { barkHandler(Event e) { myCat.run() });
In this way, I can just handle the d开发者_如何学Pythonifferent types of CatEvent in different eventHandler class and functions and I don't have to keep creating different event listener methods for different events?
Maybe I am missing something out about Java's event handling but is there a neater way that I don't have to keep copy and paste the 3 methods plus creating so many different kind of event objects for every different kind of methods I want to dispatch?
Thanks!
The event handling strategy I have is to publish by type which may suit you.
I have a broker which can examine the listener for an annotation which marks a method as listening to events. Using this approach you only need to add methods when you want to handle a specific class of event.
interface Subscriber { // marker interface for OSGi
}
@interface SubscriberCallback { // marker annotation
}
class Broker {
// uses reflections to find methods marked with @SubscriberCallback
public void addSubscriber(Subscriber subscriber);
public void removeSubscriber(Subscriber subscriber);
public <T> void publish(T... events);
}
class MyListener implements Subscriber {
@SubscriberCallback
public void onDogEvent(DogEvent... dogEvents) {
// called for one or more dog events
}
@SubscriberCallback
public void onCatEvent(CatEvent catEvent) {
// called for each CatEvent including subsclass of CatEvent.
}
}
Then if I want to manage just one kind of CatEvent event, say Meow, (and EAT)
The "action" of the event (MEOW or EAT) should be data defined in the CatEvent. Then your event listening code would check the action type and do the appropriate processing.
Maybe take a look at the TableModelEvent to see how this is done. It handles "insert", "delete" and "update" events using the same event.
Also you could probably model a general event listener based on the PropertyChangeListener. A PropertyChangeListener is used to handle events when various properties change on a Swing component. For example when you invoke setForeground() or setBackground() or setFont() or setText() or setIcon. The PropertyChangeListener uses a getName() method to determine which property has been changed. So for the above methods the names would be "foreground", "background", "font", "text", "icon". See How to Use Property Changes Listeners for an example of how this might work.
In your case the names would be "cat" and "dog". This approach would only work if the GeneralEvent you create can contain information that is relevant to each of your events (ie. "meow" and "bark").
精彩评论