The AppBase
is the parent of App
. AppBase
is used
as a class without an Dojo Cometd dependencies so it can be launched in GWT hosted mode
for basic debugging and looking at the GUI layout.
This excerpt from AppBase.onModuleLoad()
adds a ClickListenter
to the
join button. When the button is clicked, the user name is set from the text field, the join method is called,
the join panel's visibility is set to false, and the main chat panel is added. The join method in AppBase
doesn't do anything, but the child class, App
, overrides the join method and calls out to a native
JavaScript method which calls Dojo Cometd to subscribe to chat.
Example 2. Join Code Example (excerpt from AppBase.java
)
Excerpt from web/chat-webapp/src/main/java/org/springbyexample/web/gwt/chat/client/AppBase.java
joinButton.addClickListener(new ClickListener() { public void onClick(Widget sender) { userName = joinChatTextBox.getText(); join(userName); joinChatPanel.setVisible(false); chatPanel.add(sendChatPanel, DockPanel.SOUTH); chatTextBox.setFocus(true); } });
The join method is native and has special comments before and after the body so the GWT compiler can process the method into
JavaScript. The app
variable makes a reference to this
for use in the anonymous inner function.
The call to external JavaScript starts with $wnd
which indicates to the GWT compiler that what follows
$wnd. is a native JavaScript call that is calling room.join
. The room.join
takes the user's name and three callbacks to GWT. The first one is for displaying messages, the second is for displaying a user joining,
and the last is to clear the user table.
Inside the first anonymous function, it is configured to take from
and text
values for displaying a
chat message. The app
variable created about is used to reference the App
class. This is the special syntax
the GWT compiler uses to make a reference from JavaScrip to GWT generated JavaScript. You'll notice that an @
symbol is put before the full class name, which is then followed by '::' and the name of the method along with it's signature.
Right after that the variables passed into the function are passed into App.display(String from, String text)
(method actually
located in AppBase
).
Example 3. Join Code Example (excerpt from App.java
)
Excerpt from web/chat-webapp/src/main/java/org/springbyexample/web/gwt/chat/client/App.java
protected native void join(String userName) /*-{ // Keep reference to self for use inside closure var app = this; $wnd.room.join(userName, function(from, text) { app.@org.springbyexample.web.gwt.chat.client.App::display(Ljava/lang/String;Ljava/lang/String;)(from, text); }, function(user) { app.@org.springbyexample.web.gwt.chat.client.App::addUser(Ljava/lang/String;)(user); }, function() { app.@org.springbyexample.web.gwt.chat.client.App::clearUserTable()(); } ); }-*/;
This shows the JavaScript function being called from GWT to join the chat room ($wnd.room.join
).
Example 4. Join Code Example (excerpt from gwt-chat.js)
Excerpt from src/main/webapp/js/gwt-chat.js
join: function(userName, displayCallback, addUserCallback, clearUserTableCallback) { if (userName == null || userName.length == 0) { alert('Please enter a username!'); return; } var hostName = window.location.hostname; var port = window.location.port; var contextPath = "\/chat"; var host = "http:\/\/" + hostName; if (port) { host += ":" + port; } host += contextPath; dojox.cometd.init(host + "\/cometd\/chat\/"); room.connected = true; room.userName = userName; room.displayCallback = displayCallback; room.addUserCallback = addUserCallback; room.clearUserTableCallback = clearUserTableCallback; // subscribe and join dojox.cometd.startBatch(); dojox.cometd.subscribe("/chat/demo", room, "processMessageEvent"); dojox.cometd.publish("/chat/demo", { user: room.userName, join: true, chat: room.userName + " has joined" }); dojox.cometd.endBatch(); ... },
This excerpt from AppBase.onModuleLoad()
adds a KeyboardListener
to the text box that listens
for the enter key being pressed to send a messag, and a ClickListenter
to the the send button.
Example 5. Send Code Example (excerpt from AppBase.java
)
Excerpt from web/chat-webapp/src/main/java/org/springbyexample/web/gwt/chat/client/AppBase.java
chatTextBox.addKeyboardListener(new KeyboardListener() { public void onKeyDown(Widget sender, char keyCode, int modifiers) { } public void onKeyPress(Widget sender, char keyCode, int modifiers) { if (keyCode == KEY_ENTER) { send(chatTextBox.getText()); chatTextBox.setText(""); } } public void onKeyUp(Widget sender, char keyCode, int modifiers) { } }); Button sendButton = new Button(); sendButton.setText(sendLabel); sendButton.addClickListener(new ClickListener() { public void onClick(Widget sender) { send(chatTextBox.getText()); chatTextBox.setText(""); } });
This is the send
method being called by the KeyboardListener
and ClickListenter
defined for
send that calls the native JavaScript method $wnd.room.chat
.
Example 6. Send Code Example (excerpt from App.java
)
Excerpt from web/chat-webapp/src/main/java/org/springbyexample/web/gwt/chat/client/App.java
protected native void send(String message) /*-{ $wnd.room.chat(message); }-*/;
Below is the JavaScript function being called from GWT to send a chat message ($wnd.room.chat
).
The leave button has a ClickListener
that leaves the chat room, clears the screen and chat panel,
then shows the join panel so the user can rejoin the chat.
Example 8. Leave Code Example (excerpt from AppBase.java
)
Excerpt from web/chat-webapp/src/main/java/org/springbyexample/web/gwt/chat/client/AppBase.java
leaveButton.addClickListener(new ClickListener() { public void onClick(Widget sender) { leave(userName); chatTextBox.setText(""); chatPanel.remove(sendChatPanel); clearUserTable(); clearChatTable(); joinChatPanel.setVisible(true); } });
The leave
method calls the native JavaScript room
's leave
function.
Example 9. Leave Code Example (excerpt from App.java
)
Excerpt from web/chat-webapp/src/main/java/org/springbyexample/web/gwt/chat/client/App.java
protected native void leave(String userName) /*-{ $wnd.room.leave(); }-*/;
The leave
function doesn't do anything if the user name is null
.
If the Dojo Cometd meta subscription isn't null
, it unsubscribes from the meta channel.
Then it begins a batch that unsubscribes from the chat channel and publishes that the user has left
the room before ending the batch. At the end it disconnects from Bayeux on the server.
Example 10. Leave Code Example (excerpt from gwt-chat.js)
Excerpt from src/main/webapp/js/gwt-chat.js
leave: function(){ if (!room.userName) { return; } if (room.meta) { dojo.unsubscribe(room.meta); } room.meta = null; dojox.cometd.startBatch(); dojox.cometd.unsubscribe("/chat/demo", room, "processMessageEvent"); dojox.cometd.publish("/chat/demo", { user: room.userName, leave: true, chat: room.userName + " has left" }); dojox.cometd.endBatch(); room.userName = null; dojox.cometd.disconnect(); },