The GWT Client uses Dojo Cometd to subscribe to the list of servers and symbols they have. These are displayed in the left hand menu. When a symbol is clicked on, this subscribes to the symbol's Bayeux channel and adds a summary widget to the screen. Whenever updates are received for any Bayeux message the JavaScript uses a GWT callback to display the information.
This adds a summary widget for the symbol that was clicked to the screen and also subscribes to it's channel.
The DeferredCommand
frees up the event processing thread in the browser and queues the processing
to be done later. This can create a more responsive environment for the user by letting the browser
handle events in a more timely manner.
There is a unique key for each symbol based on the server name and symbol name. This is used to check in a
Map
if there is a already a widget on the screen for this symbol or not. If there isn't,
A new SummaryWidget
is created. This is the custom GWT component used to display summary information.
Besides passing in the server and symbol name, it also creates a SummaryCloseListener
which handles
removing the widget and unsubscribing from the symbol's Bayeux channel if the summary window is closed.
The widget is added to the Map
of widgets. This Map
is used to manage the active
summary widgets. Then the method subscribes to the symbol's Bayeux channel for updates.
Example 3. Subscribe Code Example (excerpt from AppBase.java
)
Excerpt from web/trade-monitor-webapp/src/main/java/org/springbyexample/web/gwt/monitor/client/AppBase.java
protected void addSummaryWidget(final String serverName, final String symbol) { DeferredCommand.addCommand(new Command() { public void execute() { // server name and symbol String key = getTradeKey(serverName, symbol); if (!hSummaryWidgets.containsKey(key)) { SummaryWidget summary = new SummaryWidget(serverName, symbol, key, new SummaryCloseListener(key)); centerTable.add(summary); hSummaryWidgets.put(key, summary); // subscribe this summary to it's feed subscribe(getChannel(serverName, symbol)); } } }); }
The subscribe
method passes in two callbacks to the native JavaScript's monitor.subscribe
function.
The $wnd
indicates to the GWT compiler that this is a call to native JavaScript. The first callback is
to display the list of servers and their symbols and the second is to display any incoming trade summary information.
Example 4. Subscribe Code Example (excerpt from App.java
)
Excerpt from web/trade-monitor-webapp/src/main/java/org/springbyexample/web/gwt/monitor/client/App.java
protected native void subscribe() /*-{ // Keep reference to self for use inside closure var app = this; $wnd.monitor.subscribe( function(servers) { app.@org.springbyexample.web.gwt.monitor.client.App::displayServers(Lcom/google/gwt/core/client/JsArray;)(servers); }, function(trade) { app.@org.springbyexample.web.gwt.monitor.client.App::displayTrade(Lorg/springbyexample/web/gwt/monitor/client/bean/TradeSummaryInfo;)(trade); } ); }-*/;
The subscribe
function just sets the two callbacks passed from GWT to local variables
and subscribes to any existing subscriptions. The default one configured is the one with the
list of available servers and symbols for display in the menu. Each subscription
is given the callback of the monitor
variable and processMessageEvent
function.
Example 5. Subscribe Code Example (excerpt from monitor.js)
Excerpt from src/main/webapp/js/monitor.js
subscribe: function(displayCallback, tradeDisplayCallback) { monitor.displayCallback = displayCallback; monitor.tradeDisplayCallback = tradeDisplayCallback; for (var i = 0; i < monitor.subscriptions.length; i++) { dojox.cometd.subscribe(monitor.subscriptions[i], monitor, "processMessageEvent"); } },
When a trade summary event comes in from the server, the processMessageEvent
function
in monitor.js will be called since it was registered as the callback
for all Bayeux subscriptions. It will then process the appropriate GWT callback to display the information.
If there isn't any message data, the function returns. If there is and it is the subscription to
/monitor/servers (the main server list channel), it calls the monitor.displayCallback
callback. Otherwise the monitor.tradeDisplayCallback
is called to display the trade summary update for a symbol.
Example 6. Display Trade Summary Code Example (excerpt from monitor.js)
Excerpt from src/main/webapp/js/monitor.js
processMessageEvent: function(message) { if (!message.data) { return; } if (message.channel == "/monitor/servers") { monitor.displayCallback(message.data); } else { monitor.tradeDisplayCallback(message.data); } }
The monitor.tradeDisplayCallback
callback from monitor.js is a reference to
AppBase.displayTrade(final TradeSummaryInfo trade)
. It gets the key for the trade, looks up the summary widget,
and call update on it. The JavaScript data passed into GWT is mapped into TradeSummaryInfo
which extends
TradeInfo
, but TradeInfo
extends JavaScriptObject
. Mapping JavaScript data to a GWT class
is just creating native methods that return the correct value from the JavaScript data instance
(ex: public final native String getSymbol() /*-{ return this.symbol; }-*/;
).
Example 7. Display Trade Summary Code Example (excerpt from AppBase.java
)
Excerpt from web/trade-monitor-webapp/src/main/java/org/springbyexample/web/gwt/monitor/client/AppBase.java
public void displayTrade(final TradeSummaryInfo trade) { String key = getTradeKey(trade.getServerName(), trade.getSymbol()); SummaryWidget summary = hSummaryWidgets.get(key); summary.update(trade); }