Home >> Miscellaneous
>> Google-GWT-Example
Inspired by the talk by Ray Ryan at Google I/O 2009 entitled Google Web Toolkit Architecture:
Best Practices For Architecting Your GWTApp
In this Page I shall try to demonstrate a very simple example using Google GWT Toolkit.
For this example I shall be using Eclipse Version 3.5 with Google GWT Plugin
for Eclipse.
Steps to create and set this example to execute this instantly as follows:
1. Create a new Web Application Project using Google GWT Toolkit Menu Option:
2. Appropriate values to be used for this example is as shown below:
3. Following image will show most of those files those are automatically
generated and placed in various folders under the main project:
4. By opening web.xml file that is generated by GWT Plugin is as follows:
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<!-- Servlets -->
<servlet>
<servlet-name>greetServlet</servlet-name>
<servlet-class>com.techienjoy.example.server.GreetingServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>greetServlet</servlet-name>
<url-pattern>/myexample/greet</url-pattern>
</servlet-mapping>
<!-- Default page to serve -->
<welcome-file-list>
<welcome-file>MyExample.html</welcome-file>
</welcome-file-list>
</web-app>
|
|
As you might have observed in the above web descriptor file, there is a
Servlet class, corresponding url mapping and a welcome HTML file is
already present. This means the GWT Plugin for Eclipse has already provided
some default implementation just ready to be used as it is.
5. This example package structure includes
"com.techienjoy.example" -> MyExample.gwt.xml
"com.techienjoy.example.client" -> GreetingService.java
-> GreetingServiceAsync.java
-> MyExample.java
"com.techienjoy.example.server" -> GreetingServiceImpl.java
In order to run this example we have to generate required files by using "GWT Compile"
Menu option as shown in the image below:

6. After executing compile button, one can see a folder "myexample" will get created
and many files are automatically formed within this folder.

7. All those files and folder present in the war folder under MyExample GWT
Web Application Project is an expanded form of any web application as such.
So contents from this war folder can be copied to any web application server
of one's choice and that's it.... by starting web server one can access
this example Page "MyExample.html"
I have used Apache Tomcat web server for deploying this example
and the URL I have used to start this example is as follows:
http://localhost:8080/myexample/MyExample.html
Once this example is running successfully, now we can go through all files, those
are used to form this example:
A) GWT specific XML file MyExample.gwt.xml file under com.techienjoy.example folder.
This file contains a module name "myexample", some of those inherits such as
inheriting Core Web Toolkit related, style/theme, entry point class file and
all the source path relative to the entry point class file. In this example
"client" is the source path that is required for this example to compile.
B) A custom class that extends GWT API's
"com.google.gwt.user.server.rpc.RemoteServiceServlet" ad implement this example
specific service interface with the business method contained in it.
C) GreetingService interface extends GWT API's RemoteService interface and has
a method that basic example's business method.
D) GreetingServiceAsync interface is also present in the same folder and is having
a method that is an asynchronous version of the business method that is present
in the GreetingService interface.
E) MyExample is the entry point class for this example, should implements
"com.google.gwt.core.client.EntryPoint" interface from GWT API.
F) MyExample class should implement onModuleLoad method from the EntryPoint interface
from GWT API.
This class file should be using GWT Widgets to provide appropriate screen layout
themes, styles, UI components and receiving async callbacks in form of overridden
methods.
MyExample.java
.....
.....
/**
* Entry point classes define onModuleLoad().
*/
public class MyExample implements EntryPoint {
.....
.....
greetingService.greetServer(textToServer,
new AsyncCallback() {
public void onFailure(Throwable caught) {
// Show the RPC error message to the user
dialogBox
.setText("Remote Procedure Call - Failure");
serverResponseLabel
.addStyleName("serverResponseLabelError");
serverResponseLabel.setHTML(SERVER_ERROR);
dialogBox.center();
closeButton.setFocus(true);
}
public void onSuccess(String result) {
dialogBox.setText("Remote Procedure Call");
serverResponseLabel
.removeStyleName("serverResponseLabelError");
serverResponseLabel.setHTML(result);
dialogBox.center();
closeButton.setFocus(true);
}
});
.....
.....
|
The above class files has many lines of code those are automatically generate
by GWT Plugin for Eclipse, but the portion of code of interest in the lines marked in
red as shown above.
One thing I would like to say is that there is a method greetServer that takes
two argument, one is a String text and other is a AsyncCallback having
overridden onFailure and onSuccess methods. If this pattern is followed to
create all entry points and various service methods with all calls to these
service method having own set of these two methods "onFailure" and "onSuccess"
then just one can imagine how difficult and quite messy code will be though.
Having seen the video as mentioned in this page's starting paragraph, and
inspired to try out command pattern and signle entry point for many operations
for this example using Google GWT. Benefit of this approach is to have single
servlet for all operations and all pages will be calling server through a single
method, thus better control over entry point for all server side calls.
No need to provide overridden methods for onFailure and onSuccess methods,
on every async call to server, thus duplication of code can be avoided.
Now let us do a code walk-through for a modified version of this example,
I have given a name as "MessageBoard" and it has various files as shown below:
Let us go through these files and then we can go through the difference in
design and code from the earlier example, though both MyExample and MessageBoard
does the same thing but with a difference in the way these are implemented.
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<!-- Servlets -->
<servlet>
<servlet-name>messageboardServlet</servlet-name>
<servlet-class>com.iqtf.server.MessageBoardServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>messageboardServlet</servlet-name>
<url-pattern>/messageboard/execute</url-pattern>
</servlet-mapping>
<!-- Default page to serve -->
<welcome-file-list>
<welcome-file>MessageBoard.html</welcome-file>
</welcome-file-list>
</web-app>
|
MessageBoard.html
....
....
<script type="text/javascript" language="javascript" src="messageboard/messageboard.nocache.js"></script>
....
....
|
MessageBoardExample
src
com.iqtf
MessageBoard.gwt.xml
<?xml version="1.0" encoding="UTF-8"?>
<module rename-to='messageboard'>
<!-- Inherit the core Web Toolkit stuff. -->
<inherits name='com.google.gwt.user.User'/>
<!-- Inherit the default GWT style sheet. You can change -->
<!-- the theme of your GWT application by uncommenting -->
<!-- any one of the following lines. -->
<inherits name='com.google.gwt.user.theme.standard.Standard'/>
<!-- <inherits name='com.google.gwt.user.theme.chrome.Chrome'/> -->
<!-- <inherits name='com.google.gwt.user.theme.dark.Dark'/> -->
<!-- Other module inherits -->
<!-- Specify the app entry point class. -->
<entry-point class='com.iqtf.client.MessageBoard'/>
<!-- Specify the paths for translatable code -->
<source path='client'/>
<source path='request'/>
<source path='response'/>
</module>
|
This file contains module name, entry point class, all other source paths
that contains other files required for compiling this example.
com.iqtf.client
MessageBoard.java
package com.iqtf.client;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.iqtf.request.Request;
import com.iqtf.response.MessageResponseFacade;
public class MessageBoard implements EntryPoint {
/**
* MessageBoardService.
*/
private final MessageBoardServiceAsync greetingService = GWT
.create(MessageBoardService.class);
/**
* This is the entry point method.
*/
@Override
public void onModuleLoad() {
final Button sendButton = new Button("Send");
final TextBox nameField = new TextBox();
nameField.setText("GWT User");
// We can add style names to widgets
sendButton.addStyleName("sendButton");
// Add the nameField and sendButton to the RootPanel
// Use RootPanel.get() to get the entire body element
RootPanel.get("nameFieldContainer").add(nameField);
RootPanel.get("sendButtonContainer").add(sendButton);
// Focus the cursor on the name field when the app loads
nameField.setFocus(true);
nameField.selectAll();
// Create the popup dialog box
final DialogBox dialogBox = new DialogBox();
dialogBox.setText("Remote Procedure Call");
dialogBox.setAnimationEnabled(true);
final Button closeButton = new Button("Close");
// We can set the id of a widget by accessing its Element
closeButton.getElement().setId("closeButton");
final Label textToServerLabel = new Label();
final HTML serverResponseLabel = new HTML();
VerticalPanel dialogVPanel = new VerticalPanel();
dialogVPanel.addStyleName("dialogVPanel");
dialogVPanel.add(new HTML("Sending name to the server:"));
dialogVPanel.add(textToServerLabel);
dialogVPanel.add(new HTML(" Server replies:"));
dialogVPanel.add(serverResponseLabel);
dialogVPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT);
dialogVPanel.add(closeButton);
dialogBox.setWidget(dialogVPanel);
// Add a handler to close the DialogBox
closeButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
dialogBox.hide();
sendButton.setEnabled(true);
sendButton.setFocus(true);
}
});
// Create a handler for the sendButton and nameField
class MyHandler implements ClickHandler, KeyUpHandler {
/**
* Fired when the user clicks on the sendButton.
*/
public void onClick(ClickEvent event) {
sendNameToServer();
}
/**
* Fired when the user types in the nameField.
*/
public void onKeyUp(KeyUpEvent event) {
if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
sendNameToServer();
}
}
/**
* Send the name from the nameField to the server and wait for a
* response.
*/
private void sendNameToServer() {
sendButton.setEnabled(false);
String textToServer = nameField.getText();
textToServerLabel.setText(textToServer);
serverResponseLabel.setText("");
Request request = new Request();
//
greetingService.execute(request, new MessageResponseFacade() {
@Override
public void passOnResults(Object obj) {
dialogBox.setText("Remote Procedure Call");
serverResponseLabel
.removeStyleName("serverResponseLabelError");
serverResponseLabel.setHTML((String) obj);
dialogBox.center();
closeButton.setFocus(true);
}
});
}
}
MyHandler handler = new MyHandler();
sendButton.addClickHandler(handler);
nameField.addKeyUpHandler(handler);
}
}
|
MessageBoardService.java
package com.iqtf.client;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
import com.iqtf.request.Request;
import com.iqtf.response.Response;
@RemoteServiceRelativePath("execute")
public interface MessageBoardService extends RemoteService {
T execute(Request request);
}
|
MessageBoardService is a remote service as is extending Remoteservice
interface from GWT, and this interface is having execute method.
This service's execute methos receives Request and returns Response.
MessageBoardServiceAsync.java
package com.iqtf.client;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.iqtf.request.Request;
import com.iqtf.response.Response;
public interface MessageBoardServiceAsync {
void execute(Request request, AsyncCallback callback);
}
|
Asynchronous interface of MessageBoardService with a callback argument
parameter.
com.iqtf.request
Request.java
package com.iqtf.request;
import com.google.gwt.user.client.rpc.IsSerializable;
public class Request implements IsSerializable {
}
|
Request class can contain values to be passed from client to server,
as of now I have no value to be passed to server.
com.iqtf.response
MessageResponseFacade.java
package com.iqtf.response;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.VerticalPanel;
public abstract class MessageResponseFacade implements AsyncCallback {
@Override
public void onSuccess(Response result) {
passOnResults(result.getResult());
}
@Override
public void onFailure(Throwable caught) {
// Create the popup dialog box
final DialogBox dialogBox = new DialogBox();
dialogBox.setText("Remote Procedure Call");
dialogBox.setAnimationEnabled(true);
final Button closeButton = new Button("Close");
final HTML serverResponseLabel = new HTML();
VerticalPanel dialogVPanel = new VerticalPanel();
dialogVPanel.addStyleName("dialogVPanel");
dialogVPanel.add(new HTML("Exception Occurred..."));
dialogVPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT);
dialogVPanel.add(closeButton);
dialogBox.setWidget(dialogVPanel);
dialogBox.show();
dialogBox.center();
//Window.alert("" + caught.getCause());
// Add a handler to close the DialogBox
closeButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
dialogBox.hide();
}
});
}
public abstract void passOnResults(Object obj);
}
|
MessageResponseFacade implements AsyncCallback and overrides onFailure and onSuccess
methods. In this example onFailure is a generic in nature and contains logic for creating
a dialog and showing the error or exception that is thrown.
onSuccess method will be calling an abstract method passOnResults and passes the result
object as an argument to this method.
Response class is the container for carrying response from server to the client.
In this example I am passing a string value as response, so this class has only
one variable of type String.
Response.java
package com.iqtf.response;
import com.google.gwt.user.client.rpc.IsSerializable;
public class Response implements IsSerializable {
private String data;
public String getResult() {
return data;
}
public void setData(String arg) {
data = arg;
}
}
|
com.iqtf.server
MessageBoardServiceImpl.java
package com.iqtf.server;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.iqtf.client.MessageBoardService;
import com.iqtf.request.Request;
import com.iqtf.response.Response;
public class MessageBoardServiceImpl extends RemoteServiceServlet implements
MessageBoardService {
@Override
public Response execute(Request request) {
Response response = new Response();
response.setData("This is a response from server");
return response;
}
}
|
*- I have not changed any of those comments and the methods those
are needed to run this example and are auto generated by the GWT plugin while creating
a web application project.
If you would like to download the source code of this example, then please
write to me at
reaching @ techienjoy.com
If anything missed out , please let me know at
techienjoy at yahoo . com
|
|
|
|
|
| Android Robots Example : |
Example using Borots using Android Platform
and source code implementing this example.
|
|
|
|
| Android Views Example : |
Example using Views using Android Platform
and source code implementing this example.
|
|
|
|
|
|
|
|
|
|
| Android ListView Example : |
Example on Android ListView and
explained with a very simple scenario
and article with appropriate screens
captured and shown.
|
|
|
|
|
|
|
|
|
|
|
| Android Canvas Example : |
Example using Canvas using Android Platform
and source code implementing this example.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| Android Gallery Example : |
Example on Android Gallery View
explained with a very simple scenario
and appropriate screens captured and shown.
|
|
|
|
|
|
|
|
|
|
|
| Android NFC Example : |
Example using NFC using Android Platform
and source code implementing this example.
|
|
|
|
|
|
|
|
| Android Sensors Example : |
Example on Android Sensors Listed and
explained with a very simple scenario
and article with appropriate screens
captured and shown.
|
|
|
|
|
| Android Intent Example : |
Example using Intent from Android Platform
and source code implementing this example.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| Android GridView Example : |
Example using GridView Widget using Android Platform
and source code implementing this example.
|
|
|
|
|
|
|
|
|
|
|
| Android Tab View Example : |
Example on Android Tab View
explained with a very simple scenario
and appropriate screens captured and shown.
|
|
|
|
|
|
|
| Android ListView Example : |
Example on Android ListView
explained with a very simple scenario
whereby showing folder and files with
structure and appropriate screens
captured and shown.
|
|
|
|
|
|
|
|
| Google GWT Example : |
Example using GWT and some design patterns and various
ways of implementing this example.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| Android Draw Example : |
Example using Draw using Android Platform
and source code implementing this example.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| Android ListView Example : |
Example on Android List View
explained with a very simple scenario
and article with appropriate screens
captured and shown.
|
|
|
|
|
|
| Android Examples : |
List of ANDROid examples
with source code and output
screens captured and shown.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|