
Introduction to the Google Web Toolkit Framework
Google Web Toolkit (GWT) is an open source web development framework that allows
developers to easily create high-performance AJAX applications using Java. With GWT, you
are able to write your front end in Java, and it compiles your source code into highly optimized,
browser-compliant JavaScript and HTML. "Writing web apps today is a tedious and error-prone
process. You spend 90% of your time working around browser quirks, and JavaScript's lack
of modularity makes sharing, testing, and reusing AJAX components difficult and fragile.
It doesn't have to be that way," reads the Google
Web Toolkit site.
In this tutorial, you learn how the above principles are applied to real applications. At
the same time, you are introduced to NetBeans IDE's support for GWT and you build a simple
application that makes use of some of these features.
Contents

To complete this tutorial, you need the following software and resources.
Notes:
- The Java download bundle enables you to optionally install the GlassFish server
and the Apache Tomcat servlet container 6.0.x. You must install one of these
to work through this tutorial.
- Rather than downloading the NetBeans GWT plugin from http://gwt4nb.dev.java.net/,
you can download and install it directly through the IDE's Plugin Manager. Choose
Tools > Plugins from the main menu and install the plugin, as shown below:
For more detailed instructions on how to install a framework plugin in the IDE, see:
Adding Support For A Web Framework.
- You can download
a sample working application for this tutorial, as well as
other
applications using GWT.
- For more information on GWT, see http://code.google.com/webtoolkit/.
For details on support for GWT in the IDE, see http://gwt4nb.dev.java.net/.
If you are familiar with GWT, you are welcome to contribute code to the GWT plugin project.
- This tutorial follows some of the examples introduced in
"Google Web Toolkit: GWT Java AJAX Programming",
by Prabhakar Chaganti, published by Packt Publishing, February 2007.
Setting Up the Environment
Begin by using the IDE to generate a basic source structure. Once you have it, you can study
it in some detail in order to understand the inner workings of GWT.
Creating the Source Structure of a GWT Application
The source structure of the application you create must include the GWT JAR files, the
GWT module project configuration file, as well as some standard artifacts such as the
Java entry point. Since you are using an IDE, you should not need to manually create
all these files. Instead, let a wizard do the work for you. Specifically, the final
panel of the New Web Application wizard is very useful in the context of creating a
GWT application.
- Choose File > New Project (Ctrl-Shift-N; ⌘-Shift-N on Mac). Under Categories,
select Web (or Java Web). Under Projects, select Web Application. Click Next.
- In step 2, Name and Location, type
HelloGWT in Project Name. You can
also specify the location of the project by typing in a path on your computer in
Project Location field. Click Next.
- In the Server and Settings step, select any server that you have registered in the
IDE. If you included Tomcat or the GlassFish server when installing the IDE, they
display in the drop-down list.
To register a server in the IDE, click the Add button to open
a wizard that guides you through the registration process.
- Specify the Java version you are using. Click Next.
Note: This tutorial supports GWT version 1.5 and
higher. GWT 1.4 does not support Java EE 5, so if you are using this version you
must also set the Java EE Version to 1.4. Otherwise, for example, Java EE 5
annotations will cause compilation errors.
- In the Frameworks step, select GWT.
When you select the GWT framework, the following fields become available:
- GWT Installation Folder: Specify the path to the folder where
you downloaded the Google Web Toolkit at the start of this tutorial. If an incorrect
path is specified, a red error message displays and you are not able to complete
the wizard.
- GWT Module: Specifies the name and location of the project module
that the IDE will generate when you complete the wizard. The project module is
an XML file that configures a GWT application. For example, it is used to specify
the class instantiated by GWT when the module is loaded. Note that this field
in the wizard also determines the main package of the application. By default,
the main package is
org.yournamehere and the project module is
Main. For purposes of this tutorial, leave the default entries
unchanged.
- Click Finish. The IDE creates the
HelloGWT project. The project contains
all of your sources, libraries, and project metadata, such as the project's Ant build
script. The project opens in the IDE. You can view its file structure in the Files
window (Ctrl-2; ⌘-2 on Mac) and its logical structure in the Projects window
(Ctrl-1; ⌘-1 on Mac).

- In the Projects window, right-click the project node and choose Run. The application is
built and a web archive (WAR) is created. It is deployed to the server. The server starts,
if it is not running already. Your computer's default browser opens and the welcome page
of the application is displayed.
Click the button and the text below it disappears.

In the next section, you explore each of the generated files in detail and examine how the
simple application above was created.
Examining the Source Structure of a GWT Application
The IDE's New Web Application wizard created several source files. Take a look at the files
and see how they relate to each other within the context of a GWT application.
Main.gwt.xml: The project module XML file, contained in the project's
root package, is an XML file that holds the complete application configuration needed
by a GWT project. The default project module generated by the wizard looks as follows:
<?xml version="1.0" encoding="UTF-8"?>
<module>
<inherits name="com.google.gwt.user.User"/>
<entry-point class="org.yournamehere.client.MainEntryPoint"/>
<!-- Do not define servlets here, use web.xml -->
</module>
The elements in the default project module are as follows:
inherits: Specifies modules inherited by this module.
In this simple case, we only inherit the functionality provided by the User
module, which is built into the GWT framework. When your application becomes more
complex, module inheritance lets you reuse pieces of functionality in a quick and
efficient way.
entry-point: Refers to the class that will be instantiated
by the GWT framework when the module is loaded.
Note: For more information, see:
Organizing Projects: Module XML Files.
MainEntryPoint.java: The class designating the application's
main entry point, as specified in Main.gwt.xml. It extends the
EntryPoint
class, and when the GWT module is loaded by the framework, this class is instantiated and
its onModuleLoad() method is automatically called. The default entry point
generated by the wizard looks as follows.
package org.yournamehere.client;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
public class MainEntryPoint implements EntryPoint {
/** Creates a new instance of MainEntryPoint */
public MainEntryPoint() {
}
/**
The entry point method, called automatically by loading a module
that declares an implementing class as an entry-point
*/
public void onModuleLoad() {
final Label label = new Label("Hello, GWT!!!");
final Button button = new Button("Click me!");
button.addClickListener(new ClickListener(){
public void onClick(Widget w) {
label.setVisible(!label.isVisible());
}
});
RootPanel.get().add(button);
RootPanel.get().add(label);
}
}
In the above snippet, EntryPoint's
default onModuleLoad() method adds the following components to the application:
welcomeGWT.html: The generated HTML host page, which is
the designated welcome file for the application. The web.xml file uses the
welcome-file element to specify that the host page is the initial page
displayed in the browser when the application is deployed. The host page references
the path to the JavaScript source code, and can reference the application stylesheet.
The default host page generated by the wizard looks as follows:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name='gwt:module' content='org.yournamehere.Main=org.yournamehere.Main'>
<title>Main</title>
</head>
<body>
<script language="javascript" src="org.yournamehere.Main/org.yournamehere.Main.nocache.js"></script>
</body>
</html>
The meta and script tags in the above snippet hold special
significance for GWT:
meta: Points to the application's project directory.
This tag provides the link between the HTML page and the application.
script: Imports code from the GWT framework's JavaScript
file. This file contains the code required to bootstrap the GWT framework. It
uses the configuration in the project module and then dynamically loads the JavaScript
created by compiling the entry point to present the application. The JavaScript
file is generated by the GWT framework when you run the application in hosted
mode or when you compile the application.
Creating an AJAX Random Quote Generator
In this section, you display a random quote on the web page. This example application familiarizes
you with the various components of a GWT application. The random quote is to be selected from
a list of quotes stored on the server. Every second the application retrieves the random quote
provided by the server and displays it on the web page in true AJAX style, that is, without the
user needing to refresh the page.
In the process of creating this functionality, you make use of a GWT RPC
(Remote
Procedure Call) service.
Generating the Service Stubs
The NetBeans GWT plugin provides a wizard for creating an
RPC
service. The wizard generates the basic service classes for you. This subsection
introduces the GWT RPC Service wizard.
- Click the New File (
) icon in the IDE's main toolbar. In the New File wizard,
the Google Web Toolkit category shows a file template named GWT RPC Service.
Select GWT RPC Service and click Next.
- Optionally, fill in a subpackage where the files that will be generated will be stored.
For purposes of this tutorial, type
sampleservice as the Subpackage field.
Note: By leaving the Create Usage Example Class option
selected in this step, you allow the IDE to generate the GWTServiceUsageExample
class, which can be used to invoke the service.
- Click Finish. The files listed in the New GWT RPC Service wizard (shown in the above image)
are generated, and the Projects window automatically updates to reflect changes.
Examining the Generated Classes
The GWT RPC Service wizard creates several source files. Here, look at the files and
see how they relate to each other within the context of a GWT service.
For an extended description of GWT service classes, see
Creating Services.
GWTService: The
client-side definition of the service. This interface extends the
RemoteService
tag interface.
package org.yournamehere.client.sampleservice;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
@RemoteServiceRelativePath("sampleservice/gwtservice")
public interface GWTService extends RemoteService {
public String myMethod(String s);
}
GWTServiceImpl: The servlet
that implements the GWTService interface and provides the functionality for
retrieving a random quote via RPC.
package org.yournamehere.server.sampleservice;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import org.yournamehere.client.sampleservice.GWTService;
public class GWTServiceImpl extends RemoteServiceServlet implements GWTService {
public String myMethod(String s) {
// Do something interesting with 's' here on the server.
return "Server says: " + s;
}
}
GWTServiceAsync: An
asynchronous interface, which is based on the original GWTService
interface. It provides a callback object that enables the asynchronous communication
between server and client.
package org.yournamehere.client.sampleservice;
import com.google.gwt.user.client.rpc.AsyncCallback;
public interface GWTServiceAsync {
public void myMethod(String s, AsyncCallback<String> callback);
}
GWTServiceUsageExample:
The sample user interface generated as a test client. It can be used to invoke the service.
package org.yournamehere.client.sampleservice;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
public class GWTServiceUsageExample extends VerticalPanel {
private Label lblServerReply = new Label();
private TextBox txtUserInput = new TextBox();
private Button btnSend = new Button("Send to server");
public GWTServiceUsageExample() {
add(new Label("Input your text: "));
add(txtUserInput);
add(btnSend);
add(lblServerReply);
// Create an asynchronous callback to handle the result.
final AsyncCallback<String> callback = new AsyncCallback<String>() {
public void onSuccess(String result) {
lblServerReply.setText(result);
}
public void onFailure(Throwable caught) {
lblServerReply.setText("Communication failed");
}
};
// Listen for the button clicks
btnSend.addClickHandler(new ClickHandler(){
public void onClick(ClickEvent event) {
// Make remote call. Control flow will continue immediately and later
// 'callback' will be invoked when the RPC completes.
getService().myMethod(txtUserInput.getText(), callback);
}
});
}
public static GWTServiceAsync getService() {
// Create the client proxy. Note that although you are creating the
// service interface proper, you cast the result to the asynchronous
// version of the interface. The cast is always safe because the
// generated proxy implements the asynchronous interface automatically.
return GWT.create(GWTService.class);
}
}
Now, modify the entry point class to invoke the service by instantiating a
GWTServiceUsageExample object. Recall from the previous subsection
that the GWTServiceUsageExample class was generated because you
selected the Create Usage Example Class option in the
GWT RPC wizard.
- In the
onModuleLoad() method of the application's main entry
point (MainEntryPoint.java), remove the GWT Label
and Button, and add a new instance of GWTServiceUsageExample
to the RootPanel.
public void onModuleLoad() {
RootPanel.get().add(new GWTServiceUsageExample());
}
Note: After modifying the onModuleLoad() method,
you need to add an import statement to the sampleservice.GWTServiceUsageExample
class. To do so, click on the hint that displays in the left column where the
GWTServiceUsageExample() method appears in the editor and choose Add Import
for org.yournamehere.client.sampleservice.GWTServiceUsageExample.

- In the Projects window, right-click the project node and choose Run.
The server starts, if it is not running already. The project is compiled (recompiled in this case)
and deployed to the server. The browser opens to display a text field. Type in a message and
click the button. A label appears with the message you sent.
You successfully created a GWT RPC service using the IDE's GWT RPC wizard. You then
added a GWTServiceUsageExample instance to the onModuleLoad()
method of the application's main entry point, which causes the application to invoke
the service when it is run. In the next section, you customize the service by extending
the generated classes, and attach a stylesheet to the HTML host page.
Extending the Generated Classes
In this section, you tweak and extend the classes that were examined in the previous subsection.
At the end of this subsection, you will have created a functioning version of the AJAX random quote
generator.
- Recall that
GWTServiceImpl is the servlet that
implements the service you are creating.
If you open your application's web.xml deployment
descriptor, you see that a servlet declaration and mapping have already been added.
<servlet>
<servlet-name>GWTService</servlet-name>
<servlet-class>org.yournamehere.server.sampleservice.GWTServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>GWTService</servlet-name>
<url-pattern>/org.yournamehere.Main/sampleservice/gwtservice</url-pattern>
</servlet-mapping>
In the GWTServiceImpl class, you implement the GWTService
interface with the logic that is
specific to your service. To create a random quote generator, add the following code to
GWTServiceImpl:
public class GWTServiceImpl extends RemoteServiceServlet implements GWTService {
private Random randomizer = new Random();
private static final long serialVersionUID = -15020842597334403L;
private static List quotes = new ArrayList();
static {
quotes.add("No great thing is created suddenly - Epictetus");
quotes.add("Well done is better than well said - Ben Franklin");
quotes.add("No wind favors he who has no destined port - Montaigne");
quotes.add("Sometimes even to live is an act of courage - Seneca");
quotes.add("Know thyself - Socrates");
}
public String myMethod() {
return (String) quotes.get(randomizer.nextInt(5));
}
}
Note: Right-click anywhere in the IDE's editor and choose
Fix Imports to let the IDE create the correct import statements. When you do so, make sure
to select java.util.Random instead of
com.google.gwt.user.client.Random:

- Instead of having the generated usage example class (
GWTServiceUsageExample)
invoke the service, have it invoked directly from the application's entry point class
(MainEntryPoint). Begin by copying GWTServiceUsageExample's
getService() method and paste it into MainEntryPoint.
(Changes in bold.)
public class MainEntryPoint implements EntryPoint {
/**
* Creates a new instance of MainEntryPoint
*/
public MainEntryPoint() {
}
public static GWTServiceAsync getService() {
// Create the client proxy. Note that although you are creating the
// service interface proper, you cast the result to the asynchronous
// version of the interface. The cast is always safe because the
// generated proxy implements the asynchronous interface automatically.
return GWT.create(GWTService.class);
}
...
- Right-click in the editor and choose Fix Imports. The following
three import statements are added to
MainEntryPoint.
import com.google.gwt.core.client.GWT;
import org.yournamehere.client.sampleservice.GWTService;
import org.yournamehere.client.sampleservice.GWTServiceAsync;
- Change the
onModuleLoad() method in the entry point class
to the following:
/**
* The entry point method, called automatically by loading a module
* that declares an implementing class as an entry-point
*/
public void onModuleLoad() {
final Label quoteText = new Label();
Timer timer = new Timer() {
public void run() {
//create an async callback to handle the result:
AsyncCallback callback = new AsyncCallback() {
public void onFailure(Throwable arg0) {
//display error text if we can't get the quote:
quoteText.setText("Failed to get a quote");
}
public void onSuccess(Object result) {
//display the retrieved quote in the label:
quoteText.setText((String) result);
}
};
getService().myMethod(callback);
}
};
timer.scheduleRepeating(1000);
RootPanel.get().add(quoteText);
}
- Right-click in the editor and choose Fix Imports. When you do so,
make sure to select
com.google.gwt.user.client.Timer,
and com.google.gwt.user.client.ui.Label.
- Delete the class
GWTServiceUsageExample. It will
no longer compile. Because the application is able to
call the service from its main entry point class, you no longer need the
GWTServiceUsageExample usage example class to invoke the service.
- Although the generated stubs for
GWTService and
GWTServiceAsync provided you with a String
parameter for myMethod(), you do not need it for the random quote generator.
In the GWTService class, remove the String parameter from myMethod()
so that the interface is as follows.
public interface GWTService extends RemoteService {
public String myMethod();
}
- The method signature for the asynchronous service (
GWTServiceAsync)
must match that of GWTService (but include an AsyncCallback
object as the final parameter). Therefore, remove the String parameter from
myMethod() so that the interface is as follows.
public interface GWTServiceAsync {
public void myMethod(AsyncCallback callback);
}
See Making
Asynchronous Calls and Getting
Used to Asynchronous Calls in the official GWT documentation for more
information on the asynchronous service interface.
- Run the project. When the application is deployed and the browser opens, you see a
new quote received from the server after every second:
In the next section, you apply a stylesheet to change the appearance of the quotes.
Customizing the Appearance
In this section, you attach a stylesheet to the HTML host page. You also refer to it in the
entry point class. Specifically, you need to set the style name of the label in the entry
point class to the name of the style in the stylesheet. At runtime, GWT connects the style
to the label and displays a customized label in the browser.
- Create a stylesheet called
welcomeGWT.css. To create the file, right-click the
Web Pages node in the Projects window and choose New > Other. The New File wizard
displays.
- Under Categories choose Web, then choose Cascading Style Sheet under
File Types. When you complete the wizard, the new empty file opens in the
editor.
- Create the following
quoteLabel selector for the new stylesheet.
.quoteLabel {
color: white;
display: block;
width: 450px;
padding: 2px 4px;
text-decoration: none;
text-align: center;
font-family: Arial, Helvetica, sans-serif;
font-weight: bold;
border: 1px solid;
border-color: black;
background-color: #704968;
text-decoration: none;
}
The stylesheet editor should now show the following.
To display the CSS Preview and Style Builder, choose Window
> Other from the main menu.
- Link to the stylesheet from the application welcome page (
welcomeGWT.html).
At the same time, add some text to introduce the application to the user. The new
parts of the HTML page are highlighted below in bold.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name='gwt:module' content='org.yournamehere.Main=org.yournamehere.Main'>
<link rel="stylesheet" type="text/css" href="welcomeGWT.css">
<title>Main</title>
</head>
<body>
<script language="javascript" src="org.yournamehere.Main/org.yournamehere.Main.nocache.js"></script>
<p>This is an AJAX application that retrieves a random quote from
the Random Quote service every second. The data is retrieved
and the quote updated without refreshing the page!</p>
</body>
</html>
- Within the
onModuleLoad() method of the entry point class (MainEntryPoint.java),
specify that, upon success, the style defined in the stylesheet should be applied
to the label. The new line is highlighted in bold below.
public void onSuccess(Object result) {
//display the retrieved quote in the label:
quoteText.setText((String) result);
quoteText.setStyleName("quoteLabel");
}
As you type, press Ctrl-Space to enable the IDE's built-in code completion.
The code completion works by triggering a pop-up window that suggests ways of
completing the code, and showing you the related Javadoc.
You can also open the IDE's Javadoc window if you want continuous
access to GWT documentation when working in the IDE. To do so, choose Window > Other
> Javadoc from the main menu. Notice that when you type in the editor, the documentation
in the Javadoc window updates according to your cursor's position.

- In the Projects window, right-click the project node and choose Run. This time, the label
is shown with a custom style, using the stylesheet you created in this subsection.
Compiling and Debugging
Open the Files window (Ctrl-2; ⌘-2 on Mac) and expand the build folder. (If the build
folder is not present, you need to build the project again in order to have the IDE regenerate
the build folder.) You should see something like the following:
This folder is generated automatically by GWT when the application is compiled. The folder
consists of a ready-to-deploy version of the client application. For an explanation of what
these files represent, see the Google
Code FAQ - What's with all the cache/nocache stuff and weird filenames?.
Also, note that you can take advantage of the IDE's built-in debugger
when working with GWT applications. This enables you to debug
in GWT's hosted mode. The GWT and hosted mode main window and web browser open
automatically.
Note for Mac OS X users: GWT's hosted mode is compiled for 32-bit
architecture on Mac OS X, which exists only for Java 1.5. If you are running a 64-bit version of
Java 1.6, you need to switch to a 32-bit version. You can do this using the Java Preferences panel
in OS X. After switching Java versions, you should restart the IDE.
Set field, method and line breakpoints in your source files by clicking in the left
margin of the IDE's editor.
Then simply choose Debug as you normally would for any web project (e.g., right-click the project
node and choose Debug, or click the Debug Project icon ( ). The application freezes on any breakpoint you set, allowing you
to step through code and examine variable and expression values (e.g., Choose Window > Debugging
> Local Variables to view values in the Local Variables window).
You can also hover over an expression or value in the editor, and the
debugger uses a pop-up to inform you of the current value (as shown in the above image).
GWT's hosted mode main window and web browser open. The browser displays a running version of your
application.

Conclusion
In this tutorial, you have learned the following:
- What a typical application source structure looks like in a Google Web Toolkit application.
- How Google Web Toolkit artifacts relate to each other.
- How to set up the IDE to use the Google Web Toolkit.
- What the tools are that are available to you in the IDE, specifically for using
the Google Web Toolkit.
Because the GWT framework handles browser-related code generation, as well as the creation
of the lower-level XmlHttpRequest API code, you can take advantage of the
framework to focus on the functionality that you want your applications to provide.
Hence, as stated in the introduction, GWT lets you avoid the headaches associated with browser
compatibility while simultaneously letting you offer users the same dynamic, standards-compliant
experience that the Web 2.0 world typically provides. As this tutorial demonstrated, you can
apply the GWT framework to write your complete front end in Java, because you know that you
can let the GWT compiler convert Java classes to browser-compliant JavaScript and HTML.
And, as also demonstrated, the IDE provides a complete set of tools for making all this easy
and efficient, without the need to hand-code a GWT application's basic infrastructure.
See Also
This concludes the Introduction to the Google Web Toolkit Framework tutorial. For related
and more advanced material, see the following resources:
GWT Resources
NetBeans Documentation for Java Web Frameworks
|
|