Hello, I have tried out an extremely simple (stripped down) EventBus design for allowing UI components to interact with each other in a loosely coupled way.
The design is influenced by the excellent EventBus project by Michael Bushe.
Here is a simple scenario...
A DynamicForm reads keywords from a "Keywords" TextItem when it Search Button is clicked. It then performs a search via a DataSource using the keywords as query param for the datasource.dataUrl. It then creates a ListGrid that displays the results and published the ListGrid as an Event to a topic named "SearchResults" on a new EventBus class.
Elsewhere in the UI a TabSet is subscribed to the EventBus for the "SearchResults" topic. Whenever a ListGrid is published on the "SearchResults" topic it receives the event on onEvent listener method and adds the ListGrid as a Tab within itself.
The DynamicForm (publisher) and TabSet (Subscriber) do not know about each other (are loosely coupled and communicate via the EventBus as an intermediary.
Here is the simple code for the EventBus and above example. I would appreciate thoughts on this. It does work BTW:
Here is the EventBus class itself:
Here is the TopicSubscriber interface that is implemented by subscriber (TabSet in example):
Here is the form Button's onClickHandler that publishes ListGrid to EventBus as an Event publisher:
Here is the code for the customized TabSet sub-class which is the TopicSubscriber and receives events:
Please share any thoughts on this extremely light-weight and simple design for loosely coupled pub/sub communication and wiring between components in GWT/SmartGWT.
Are there pitfalls that I am not seeing?
The design is influenced by the excellent EventBus project by Michael Bushe.
Here is a simple scenario...
A DynamicForm reads keywords from a "Keywords" TextItem when it Search Button is clicked. It then performs a search via a DataSource using the keywords as query param for the datasource.dataUrl. It then creates a ListGrid that displays the results and published the ListGrid as an Event to a topic named "SearchResults" on a new EventBus class.
Elsewhere in the UI a TabSet is subscribed to the EventBus for the "SearchResults" topic. Whenever a ListGrid is published on the "SearchResults" topic it receives the event on onEvent listener method and adds the ListGrid as a Tab within itself.
The DynamicForm (publisher) and TabSet (Subscriber) do not know about each other (are loosely coupled and communicate via the EventBus as an intermediary.
Here is the simple code for the EventBus and above example. I would appreciate thoughts on this. It does work BTW:
Here is the EventBus class itself:
Code:
/** * A very simple EventBus for loosely coupled event driven coupling between components. * There is no buffering and events are lost if no listeneres are registered when event is published. * Events are relayed serially to Listener in order that they were added. * * @author najmi */ public class EventBus { static Map<String, List<TopicSubscriber>> topicSubscribersMap = new HashMap<String, List<TopicSubscriber>>(); /** * Publish an Object to a topic. * * @param topic the topic being published to * @param o the event object being published */ public static void publish(String topic, Object o) { System.err.println("Publish entered"); List<TopicSubscriber> topicSubscribers = topicSubscribersMap.get(topic); if (topicSubscribers != null) { for (TopicSubscriber topicSubscriber : topicSubscribers) { System.err.println("Sending event to subscriber: " + topicSubscriber); topicSubscriber.onEvent(topic, o); } } } public static void subscribe(String topic, TopicSubscriber listener) { System.err.println("Subscribe entered"); List<TopicSubscriber> topicListeners = topicSubscribersMap.get(topic); if (topicListeners == null) { topicListeners = new ArrayList<TopicSubscriber>(); topicSubscribersMap.put(topic, topicListeners); } topicListeners.add(listener); } }
Code:
public interface TopicSubscriber<T> { /** * Listener that gets notified of an event on a topic. * * @param topic the topic on which event occured * @param o the event object */ public void onEvent(String topic, T o); }
Code:
searchButtonItem.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { ListGrid resultsGrid = createResultsGrid(); EventBus.publish("SearchResults", resultsGrid); } });
Code:
public class MainTabSet extends TabSet implements TopicSubscriber<Canvas> { ... public void onEvent(String topic, Canvas canvas) { if (topic.equals("SearchResults")) { Tab tab = new Tab("Result " + c.getID()); tab.setCanClose(true); tab.setPane(c); this.addTab(tab); } } }
Are there pitfalls that I am not seeing?
Comment