GWT (or the Google Web Toolkit) provides a Java library and set of tools that allow a pure JavaScript and HTML application to be derived form a Pure Java development environment. The executable is then generated from this and is implemented in terms of JavaScript, HTML and CSS etc. As such, this allows a much higher level of abstraction to be used by developers, while still generating the latest AJAX based web applications.
Why is this useful or even desirable? I believe the answer to this question is akin to the answer provided by people regarding low-level languages such as assembler and higher level programming languages such as Pascal, Ada and PL1, back when I started out in computing. By working at a higher level, we can focus on the requirements of our systems rather than the quirks of various different browsers, or the integration of various different browser based technologies. It also makes the whole development process simpler for developers who have less experience in these technologies and their integration. Remember AJAX is not so much a technology in itself as a technique integrating a number of other technologies.
Having built numerous desktop-based Swing applications, I find the development approach adopted by such environments much richer and at a higher level than a pure AJAX environment. I also believe that working at such a level reduces the number of technology-oriented bugs. GWT moves rich web client development to this level of abstraction.
In this column, we look at the technical details of actually creating a GWT based application. We will examine the structure of a very simple application and review the translation process and the final execution environment.
Basic UI Components
The basic components used within a GWT application will have a familiar feel for anyone who has ever done any AWT, Swing, or indeed SWT work. You will find that there are UI Components such as Buttons, CheckBoxes, Labels, Tables, Trees, and TextBoxes. In GWT terminology, these are called Widgets.
Widgets can be combined together using Panels (of various sorts such as Flow, Horizontal and Vertical), grids etc. You create displays by combining various widgets together in panels, much as you would combine Swing components together within JPanels
etc. For example, the following uses HorizontalPanel
with a number of Widgets added to it.
HorizontalPanel hp = new HorizontalPanel(); hp.setVerticalAlignment(VerticalPanel.ALIGN_MIDDLE); hp.add(new Button("Start")); hp.add(new HTML("<b>Welcome</b>", true)); hp.add(new Button("Stop"));
GWT also provides a number of built in widgets that are useful for AJAX applications, including hierarchical trees, menu bars, tab bars and model dialog boxes.
GWT also possesses an event handling framework that is very similar to the delegation event model used with Swing applications. This means that to write a simple call back handler for a GWT button is no harder than writing the equivalent handler for a Swing application (although some Adapter classes are missing – adapter classes are default null implementations for Event handlers that reduce the number of methods you may need to write). For example, the following code snippet implements a very simple event handler for a button:
ClickListener listener = new ClickListener() { public void onClick(Widget sender) { Window.alert("Hello GWT World"); } }; Button b = new Button("Click me", listener);
This code snippet creates an anonymous subclass of the ClickListener
that will display a message "Hello GWT World" whenever it is run. It is then used as the listener passed to the Button construct such that whenever the button is clicked the associated onClick
method will be executed. When this application is translated into AJAX, the call back mechanism will be handled completely within the JavaScript implementation.
Anatomy of a GWT application
Let us now briefly dissect the simple GWT application presented in Figure 1. Our class, HelloWorldApplication
, directly implements the EntryPoint
interface. EntryPoint
is the interface that a class can act as a module entry point. It defines a single method onModuleLoad
which is used to initialise the class (and thus potentially the module).
A module is essentially a GWT application – in a manner similar to an executable Jar for a Swing application or a WAR for a standard Java web application. A module can have zero or more entry points – these entry points allow applications to be instantiated or application behaviour to be triggered off. As well as implementing the EntryPoint
interface, an entry point class must also have a zero parameter constructor. When a module is loaded, every entry point class is instantiated and its onModuleLoad
method is called.
So, in the following class the onModuleLoad
method sets up a button, a label, creates and registers a ClickListener
with the button and adds the button and label to the RootPanel
. The RootPanel
is analogous to the root pane of a Swing application.
public class HelloWorldApplication implements EntryPoint { /** * This is the entry point method. */ public void onModuleLoad() { final Button button = new Button("Click me"); final Label label = new Label(); button.addClickListener(new ClickListener() { public void onClick(Widget sender) { if (label.getText().equals("")) label.setText("Hello World!"); else label.setText(""); } }); RootPanel.get("slot1").add(button); RootPanel.get("slot2").add(label); } }
In addition to the Java class created by the GWT tools, two other files are important. One is the GWT configuration file that specifies the location of the core web toolkit material and the entry point for the application. For the HelloWorldApplication
this is the HelloWorldApplication.gwt.xml
file presented below:
<module> <!-- Inherit the core Web Toolkit stuff. --> <inherits name='com.google.gwt.user.User'/> <!-- Specify the app entry point class. --> <entry-point class='com.regdev.client.HelloWorldApplication'/> </module>
Finally, there is the HTML file that drives the module. In our case, this is a file called HelloWorldApplication.html which looks much like any other HTML / JavaScript file with the exception of the GWT module reference:
<meta name='gwt:module' content='com.regdev.HelloWorldApplication'>
and the reference to the GWT javascript code that bootstraps the whole process:
<script language="javascript" src="gwt.js"></script>
One thing that might surprise you is the location of these files. As illustrated in Figure 2 the XML file and the HTML file are both located within the Java source package structure. This is not a mistake as the GWT tools
expect to load them from here.
Running in Hosted mode
To run your GWT application in hosted mode, all you need do is run the com.google.gwt.dev.GWTShell
that is a class that is found in the gwt-dev-windows.jar
(or gwt-dev-linux.jar
). This class takes a number of parameters including the URL to launch. For example:
com.regdev.HelloWorldApplication/HelloWorldApplication.html
This can be done in Eclipse as illustrated in Figure 3.
The application then runs in just the same way as a Swing application and can be interactively debugged in the same manner.
Running in web mode
To run in web mode you must first generate the HTML and JavaScript version of your GWT application. To do this you need to run the module compile command generated when the application was created. In our case this is the HelloWorldApplication-compile.cmd
. For example:
c:\javalibs\gwt-windows-1.0.21>HelloWorldApplication-compile.cmd Output will be written into c:\javalibs\gwt-windows-1.0.21\www\com.regdev.HelloW orldApplication Compilation succeeded
In the output directory, I now have a set of files that implement my GWT application using HTML and JavaScript. For example:
14B4BAB3B0DE05BB39CFBF9A0551F95D.cache.html 14B4BAB3B0DE05BB39CFBF9A0551F95D.cache.xml 81677B969CD0C6EB7CBB3305CEFE7DBE.cache.html 81677B969CD0C6EB7CBB3305CEFE7DBE.cache.xml B762F92F372AC2E5337520D4E5005B16.cache.html B762F92F372AC2E5337520D4E5005B16.cache.xml F360E12E64EF8D691E75006875BE43D9.cache.html F360E12E64EF8D691E75006875BE43D9.cache.xml HelloWorldApplication.html com.regdev.HelloWorldApplication.nocache.html gwt.js history.html tree_closed.gif tree_open.gif tree_white.gif
By opening HelloWorldApplication.html in a browser I can see the end result of my hard work running as a pure HTML/JavaScript application (as illustrated in Figure 4).
I could now deploy this to a web server and make my first GWT application available over the web.
Summary
GWT is an extremely interesting and useful development environment for (in particular) Java developers who want to produce rich web clients. It provides a powerful develop-debug-deploy environment that can exploit the full program creation and debug facilities in IDEs such as Eclipse.
There are of course those who will say that the AJAX code produced by the GWT can't be as efficient as that produced by hand (which may well be true, although the Google team are proud of the quality of the code automatically generated); but it also has the potential to contain fewer architectural or technology oriented bugs. Obviously, the generated client must still be tested within any browsers that will be used by end users – merely testing the pure Java version in the Eclipse IDEs is not sufficient.
In addition, the fact that this is a Google tool suite, rather than part of the Java platform itself or from the Apache Organisation may trouble some. However, as a tool in and of itself, it is one that I will be watching closely; and I will look for an opportunity to test it within the context of a real world application as soon as possible. ®