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();
},