JavaEnterprise JavaEvent Driven Programming in AJAX Using the GWT and Java

Event Driven Programming in AJAX Using the GWT and Java

Java Programming Notes # 2554


Preface

General

Historically, the development of Ajax web applications has been a complex
process. This is due mainly to the requirement to learn and use a variety of
technologies, possibly including HTML, JavaScript, XML, ASP.NET, Java servlets,
various scripting languages, etc.

Recently several products have emerged that make it possible to develop Ajax
web applications using the Java development environment. Some use exclusively
Java, while others use mainly Java.  I have discussed several of these new
programming environments in previous lessons in this series (see
Resources)
.

The Google Web Toolkit (GWT)

One development environment that allows you to use mainly Java for the
development of web applications is the Google Web Toolkit (GWT) (see
Resources and
Download)
, which is the primary topic
of this tutorial lesson.

Most of the client-side code for a GWT Ajax application can be written in
Java.  There is no requirement to write JavaScript code.

Third
in a series

This is the third lesson in a series designed to help you learn
how to use the GWT to create rich Ajax web applications.  You will find
links to the previous lessons in the series in the
Resources
section.

Purpose of the tutorial

The main purpose of the tutorial is to teach you how to write
the Java code necessary to accomplish event driven programming using the GWT. 
In addition, I will discuss my experience in upgrading from GWT version 1.1.10
to version 1.2.22.

Viewing tip

I recommend that you open another copy of this document in a separate
browser window and use the following links to easily find and view the figures
and listings while you are reading about them.  You may also find it useful
to open a third browser window at the Resources section near the end of the
document.  That will make it easy for you to open those resources when they
are mentioned in the text.

Figures

  • Figure 1. Non-symmetry in a DockPanel object.
  • Figure 2. Application GwtApp011 at startup.
  • Figure 3. Application GwtApp011 while running.
  • Figure 4. An API map of the GWT.
  • Figure 5. A screen shot at startup.
  • Figure 6. A screen shot while the application is
    running.
  • Figure 7. Screenshot at startup for GwtApp013.
  • Figure 8. A screenshot of the scrolled pool
    image.
  • Figure 9. Screenshot of the scrolled book image.
  • Figure 10. Screenshot for an invalid image file
    name.
  • Figure 11. Application GwtApp014 at startup.
  • Figure 12. Display the new size of the browser
    window.
  • Figure 13. GwtApp015 application GUI at
    startup.
  • Figure 14. The confirmation dialog for
    GwtApp015.

Listings

Supplementary material

I recommend that you also study the other lessons in my extensive collection
of online Java tutorials.  You will find a consolidated index for those
lessons at

www.DickBaldwin.com
.

Upgrade to GWT
version 1.2.22

Download the new version
You will find a link to the GWT download page in the
Resources
section.

All of the material in the two previous lessons was based on the use of the
GWT version 1.1.10.  After writing that lesson and before beginning this
lesson, I upgraded to version 1.2.22.

Appearance bug in DockPanel component

I was hopeful that the new version would resolve some of the problems
(bugs)
in the GWT that I mentioned in the earlier lessons. 
Unfortunately, that is not
the case.  For example, the bug in the DockPanel component
class that produces the non-symmetry at the bottom of Figure 1 still exists in
version 1.2.22.


Figure 1. Non-symmetry in a DockPanel object.

I explained the circumstances surrounding this bug in conjunction with
Figure 13 in the previous lesson named "Controlling layout in AJAX web
applications using the GWT and Java" (see Resources).

Missing images in javadocs

I mentioned in an earlier lesson that the javadoc version of the
documentation contained in the downloadable SDK is missing some images that
appear in the online version of the documentation.  (See the
documentation for DockPanel for example.)
  Unfortunately, those
images are still missing in version 1.2.22.

A new directory with many files

The following information is not in the nature of a bug.  Rather, it
describes something new in the operation of the SDK.

Figure 5 in the lesson named "Creating Ajax web applications using the
Google Web Toolkit (GWT) and Java, Getting Started" (see
Resources
)
showed the directory tree that results from:

  • Installing the SDK version 1.1.10
  • Creating a new application
  • Executing the shell command to run the new application in hosted mode
    under version 1.1.10

A new directory is automatically created under
version 1.2.22

I noticed in version 1.2.22 that a new directory is automatically
created and populated as a subdirectory of the directory named GwtApps
(see Figure 5 in the earlier lesson)

The name of the new directory is .gwt-cache.  That directory
contains a directory named bytecode, which contains about 150 files with
name like those shown below:

  • com.google.gwt.core.client.EntryPoint-65ae9124.tmp
  • com.google.gwt.user.client.WindowResizeListener-e489ad2a.tmp
  • GwtApp.client.GwtApp010-7d433460.tmp
  • java.io.FilterOutputStream-e5bf7a95.tmp
  • java.lang.Boolean-148d6054.tmp
  • java.lang.UnsupportedOperationException-b38824e9.tmp
  • java.util.AbstractCollection-a6b2d220.tmp
  • java.util.Vector-cb101b03.tmp

I’m not sure what the purpose of these files is, but my advice is to simply
leave them alone.  I didn’t leave them alone, and that caused me some difficulties.

A discovery regarding operational procedures

I don’t know if this circumstance is peculiar to version 1.2.22, or if I
simply didn’t discover it while working with version 1.1.10.  However, it
cost me a couple of hours of wasted time working it out.

Creating a new GWT application

One way to create a new GWT application is to execute the script named
applicationCreator
.  I accomplish this using the Windows batch file
shown in Listing 1.  (Note that everything in Listing 1 must be on a
single line.)


Listing 1. Batch file used to run the applicationCreator
script.

C:progfileGwtV1.2.22-noUninstallReq
gwt-windows-1.2.22applicationCreator GwtApp.client.%1

If you are familiar with the use of Windows batch files, you will recognize
that this allows me to specify the name of the new application as a command-line
parameter following the name of the batch file when entered on the command line.

Everything needed is automatically created

Execution of the applicationCreator script creates everything needed
for the new application, including the following two files (where the new
application is assumed to be named GwtApp015):

  • GwtApp015.java
  • GwtApp015.html

These are two of the basic files required for a new GWT application. 
You can edit them (and supplement them with additional files) to
provide the required behavior for your new application.

Edit, don’t replace

Note that I didn’t say that you can replace them; I said that you can
edit them. 

I thought that I could simply replace the two files created by the
applicationCreator
script with two different files having the same names for
the purpose of creating my new application.

After spending a
couple of hours trying to determine why my new application wouldn’t work, I
discovered that I could solve the problem by pasting the new code into the
original files created by the applicationCreator script instead of
replacing those two files with new files having the same name.  The reason
why this is true is still a mystery to me, but I have accepted it as an operational
procedure that gets the job done.  When I have a little time, I plan to
investigate it further an attempt to understand how the "hosted mode"
compiler can possibly know the difference.

General background information

Standard Java mouse events
In comparison, MouseListener and MouseMotionListener objects in
standard Java have the combined ability to handle mouse events in the following
seven sub-categories:

  • mousePressed
  • mouseReleased
  • mouseEntered
  • mouseExited
  • mouseMoved
  • mouseDragged
  • mouseClicked

As you can see, the corresponding names suggest that the first five items in
the list of standard Java mouse events have a similar behavior to the five items
in the GWT list.

Types of events

The capability of an event driven web application depends heavily
upon the
types of events that can be fired by the available GUI components as well as the
sub-categories associated with those event types.  For example, some GWT GUI components
have the ability to register event handler objects of the interface type
MouseListener
.  Those handlers can be notified of mouse events in the
following sub-categories:

  • onMouseDown
  • onMouseUp
  • onMouseEnter
  • onMouseLeave
  • onMouseMove

The event driven programming process

In both standard Java and the GWT, the event driven programming process
consists of the following steps:

  • Define a class that implements an interface having a name like
    MouseListener
    (The interface name begins with the type of
    event followed by the word Listener.)
  • Override and provide concrete definitions for all of the abstract
    methods that are declared in the interface.  (The methods typically
    have names like onMouseEnter in the GWT and mouseEntered in
    standard Java.)
      The
    behavior that results from the firing of an event is established by the code
    in the overridden methods.
  • Instantiate an object of the new class and register it on the GUI
    component that is expected to fire the event.

The JavaBeans design pattern for registration
methods

In standard Java, all (or at least most) event listener registration methods adhere
to the naming convention established by the JavaBeans design patterns.  According to the design pattern, the name of the
registration method should be:

add<EventType>listener

Window object is different
As you will see later, the procedure for registering an event listener object
on a GWT Window object is somewhat different.

For example, to register a mouse listener object on a GUI component in
standard Java, you
invoke the addMouseListener instance method on the component that is expected to
fire the event, passing a reference
to an object of the interface type MouseListener as a parameter.  It
appears that in most cases, the GWT adheres to the same naming convention and
the same procedure for event listener registration.

Event types fired by a specific component

Standard Java Button and JButton events
In comparison, the standard Java Button class defines or inherits the
following registration methods:

  • addActionListener
  • addComponentListener
  • addFocusListener
  • addHierarchyBoundsListener
  • addHierarchyListener
  • addInputMethodListener
  • addKeyListener
  • addMouseListener
  • addMouseMotionListener
  • addMouseWheelListener
  • addPropertyChangeListener

The standard Java JButton (Swing) class adds at least the
following additional registration methods to the list, and possibly some registration
methods not listed here:

  • addChangeListener
  • addItemListener
  • addAncestorListener
  • addVetoableChangeListener
  • addContainerListener

It is often necessary to determine all of the different event types that can
be fired by a specific GUI component.  The easiest way that I know of to do
this is
to identify all of the registration methods defined by and inherited into the
class from which the GUI component is instantiated.  For example, the GWT
Button class defines and inherits the following registration methods:

  • addClickListener
  • addFocusListener
  • addKeyboardListener

A fairly limited set

This is a lot fewer event types than the event types that can be fired by
buttons in standard Java.

Generally speaking, a programmer developing standard Java desktop
applications has many more tools to work with than a programmer developing GWT
web applications insofar as event handling is concerned.

All of the different types of events that can be
fired

It is also sometimes useful to determine all of the different types of events
that can be fired by one or more different types of GUI components.  One way to determine this is
to search the documentation and identify all of the listener interfaces.

Listener interfaces and registration methods

For every listener interface that can be used to create a listener object, there
should be a registration method that can be used to register that listener
object on one or more different types of GUI components.  Unless I missed
some, the following list shows all of the listener interfaces and the
corresponding registration methods that are provided by GWT 1.2.22. 
(This list also identifies the web applications that will be used to explain the
use of the corresponding type of event.)

  • ClickListener – addClickListener (See GwtApp003 in the previous lesson. 
    See Resources.)
  • ChangeListener – addChangeListener (See GwtApp011)
  • MouseListener – addMouseListener (See GwtApp012)
  • KeyboardListener – addKeyboardListener (See GwtApp013)
  • LoadListener – addLoadListener (See GwtApp013)
  • ScrollListener – addScrollListener (See GwtApp013)
  • WindowResizeListener – addWindowResizeListener (See GwtApp014)
  • WindowCloseListener – addWindowCloseListener (See GwtApp015)
  • EventListener – DOM.setEventListener
  • FocusListener – addFocusListener
  • HistoryListener – addHistoryListener
  • PopupListener – addPopupListener
  • TabListener – addTabListener
  • TableListener – addTableListener
  • TreeListener – addTreeListener

Quite a few different event types

What about the others?
A working sample application for ClickListener was provided as
GwtApp003
in a previous lesson.  I hope to be able to provide
working sample applications for the others in subsequent lessons.

As you can see from the above list, there are quite a few different event
types to work with when creating GWT web applications.  I will provide a
working sample application in this lesson for each of the event types highlighted in
boldface in the above list. 
Along the way, I will illustrate the use of several different GWT GUI
components.

Matches the JavaBeans design pattern

As you can see from the above list, except for the EventListener
interface, the
registration methods for all of the event types follow the
JavaBeans design pattern for event listener registration methods.

System events

There is another category of events in the GWT that do not require registration in order
to be processed.  For want of a better description, I have referred to them
as system events but that is probably not a very good description. 
For example, the following two methods are inherited into the Button
class, and will be executed when certain things happen.  If you want to
provide specific behavior in those cases, you can extend the Button class and override the methods to
provide that specific behavior.

  • onBrowserEvent – Fired whenever a browser event is received.
  • onLoad – This method is called when the widget becomes attached to the
    browser’s document.

These descriptions were copied from the GWT javadocs.

Preview

Five sample GWT web applications

I will present and explain five sample GWT applications in this lesson. 
The names of the five applications are shown in the following list.  This
list also shows the primary event type(s) that each application is designed to
illustrate.

Discussion
and sample code

I will discuss the code for the following applications in fragments. 
Complete listings of all of the code are provided in Listing 25 through Listing
34 near the end of the lesson.

GwtApp011 – ChangeListener

The HTML host page

The HTML host page for the application named GwtApp011 is shown in its
entirety in Listing 2.


Listing 2. Host page for GwtApp011.

<!---------------------------------------------------------
File GwtApp010.html
GWT host page.
Revised: 1/18/06
---------------------------------------------------------->
<html>
<head>
<title>Wrapper HTML for GwtApp010</title>
<meta name='gwt:module' content='GwtApp.GwtApp010'>
</head>

<body>
<script language="javascript" src="gwt.js"></script>
<iframe id="__gwt_historyFrame" 
                style="width:0;height:0;border:0"></iframe>

<h3>GwtApp010</h3>
<p>
This is a replica of the application named GwtApp005 from 
an earlier lesson. The purpose of this application is to 
determine if the upgrade to version 1.2.22 resolved the 
symmetry problem at the bottom of a DockPanel object. As 
you can see from the following image, the upgrade did not 
resolve the problem.
</p>

</body>
</html>

There is nothing in Listing 2 that is new to this lesson.  I have
explained everything in Listing 2 in one of the earlier lessons in the series. 
In general, that will also be true for the host pages for each of the
applications in this lesson.  Therefore, unless something new turns up, I
will ignore the host pages while discussing the applications in this lesson. 
However, a complete listing of the host page for each application is provided in
Listing 25 through Listing 34 near the end of the lesson.

The application GUI at startup

Figure 2 shows a screen shot of the application named GwtApp011 at startup when running in
hosted mode.


Figure 2. Application GwtApp011 at startup.

The application GUI while running

Figure 3 shows a screen shot of the application after the user has made a
selection from the drop down ListBox.   This screen shot shows
the application running in Firefox.


Figure 3. Application GwtApp011 while running.

As you can see in Figure 3, the word "Empty" has been replaced by the
selected item in the drop down ListBox.

Description of the application

The purpose of this application is to illustrate the use of the
ChangeListener
interface to register and service events on a ListBox
component.

Two ListBox objects and one Label object are placed in a
HorizontalPanel
object.  One ListBox is completely open and the
other is configured to be a drop down ListBox as shown in Figure 2.

The two ListBox objects are populated with strings and a unique name
is assigned to each ListBox.  One ListBox is named Open
ListBox
and the other is named Drop Down ListBox.

Doesn’t work with a TextBox object
Note that I tried unsuccessfully to get the ChangeListener to work
with a TextBox object.

It seems to work in the compiled version with
Firefox, but doesn’t seem to work properly in hosted mode.  In that
situation, the TextBox fires an event when you press the Enter key
after having modified the contents of the TextBox.  However, even
the compiled version doesn’t seem to work properly with IE 6.x.

An anonymous ChangeListener

An anonymous ChangeListener object is registered on each ListBox
When the user selects a new item in either ListBox, the name of the
ListBox
and the selected item are displayed in the Label
(At startup, the Label displays the word "Empty.")

Testing

This application was tested using J2SE 5.0, GWT version 1.2.22, and jakarta-tomcat-5.0.27 running
as a localhost server under WinXP.

The Java program code

The first code fragment is shown in Listing 3.

Except for the last statement, everything in Listing 3 has been explained in
earlier lessons.  That statement instantiates the Label object that
is used to display the output text produced by the event handlers as shown in
Figure 3.


Listing 3. Instantiate the Label object.

package GwtApp.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.*;

public class GwtApp011 implements EntryPoint{

  //This is the entry point method.
  public void onModuleLoad(){

    final Label label = new Label("Empty");

A final reference variable

The reference variable named label that refers to the Label
object is declared final in Listing 3, to make it accessible from within
an anonymous inner class definition later in the application.  (See the
link to the earlier lesson named "The Essence of OOP using Java, Anonymous
Classes" in Resources for more information on anonymous
inner classes.)

A ListBox object

Listing 4 instantiates and populates the ListBox component shown on
the far left in Figure 3.


Listing 4. Instantiate the first ListBox object.

    final ListBox listBoxA = new ListBox();
    listBoxA.setVisibleItemCount(4);
    listBoxA.addItem("Bill");
    listBoxA.addItem("Tom");
    listBoxA.addItem("Sue");
    listBoxA.addItem("Joe");
    listBoxA.setName("Open ListBox");

Invocation of the method named setVisibleItemCount does pretty much
what the name implies.  It establishes the number of items that are visible
in the normal (collapsed) state of the ListBox.  If the value
of the parameter is less than the number of items contained in the ListBox,
it takes on the appearance of a drop-down list as shown by the rightmost
ListBox
in Figure 3.  (The default value is 1 as shown by the
rightmost ListBox.)

Register a ChangeListener object on the ListBox

Listing 5 defines an anonymous inner class and registers an anonymous
ChangeListener
object on the ListBox shown at the left in Figure 3.  (Once
again, see the
link to the earlier lesson named "The Essence of OOP using Java, Anonymous
Classes" in Resources for more information on anonymous
inner classes.)


Listing 5. Register a ChangeListener object on the
ListBox.

    
    //Register an anonymous ChangeListener object on the
    // ListBox object.
    listBoxA.addChangeListener(
      new ChangeListener(){
        public void onChange(Widget sender){
          ListBox listBox = (ListBox)sender;
          String listBoxName = listBox.getName();
          int index = listBox.getSelectedIndex();
          String itemText = listBox.getItemText(index);
          label.setText(listBoxName + ": " + itemText);
        }//end onChange
      }//end constructor
    );//end addChangeListener

The method named onChange in Listing 5 will be executed whenever the
list box fires a change event.  The code in the method extracts the name of
the list box along with the selected item from the list box and displays that
information in the label shown on the far right in Figure 3.

Another ListBox object

Listing 6 instantiates, populates, and registers a ChangeListener on
the ListBox object shown on the right in Figure 3.


Listing 6. Another ListBox.

    final ListBox listBoxB = new ListBox();
    listBoxB.addItem("Spot");
    listBoxB.addItem("Fido");
    listBoxB.addItem("Butch");
    listBoxB.addItem("Scotty");
    listBoxB.setName("Drop Down ListBox");
    
    listBoxB.addChangeListener(
      new ChangeListener(){
        public void onChange(Widget sender){
          ListBox listBox = (ListBox)sender;
          String listBoxName = listBox.getName();
          int index = listBox.getSelectedIndex();
          String itemText = listBox.getItemText(index);
          label.setText(listBoxName + ": " + itemText);
        }//end onChange
      }//end constructor
    );//end addChangeListener

Note that the code in Listing 6 doesn’t set the number of visible items in
the list box.  Rather, it accepts the default, which causes only one item
to be visible.

A HorizontalPanel object

As you learned in an earlier lesson, the GWT provides a large number of
different components that can be used to control the layout of the GUI. 
(Also see the section named An API map of the
GWT
below.)
  One of those components is a HorizontalPanel
Listing 7 instantiates a HorizontalPanel object and populates it with the two
ListBox objects and the Label object.


Listing 7. A HorizontalPanel object.

    HorizontalPanel horizPanel = new HorizontalPanel();
    horizPanel.setSpacing(5);
    horizPanel.add(listBoxA);
    horizPanel.add(listBoxB);
    horizPanel.add(label);

According to the GWT documentation, a HorizontalPanel is a panel that
lays all of its widgets out in a single horizontal column.  (I probably
would have referred to it as a horizontal row instead of a horizontal column.)

Execution of the setSpacing method in Listing 7 establishes a spacing
of 5 pixels between each of the three components.

Add the HorizontalPanel to the browser window

Listing 8 adds the HorizontalPanel to the browser window using code
that you have seen in previous lessons.


Listing 8. Add the HorizontalPanel to the browser window.

    RootPanel.get().add(horizPanel);
    
  }//end onModuleLoad method
}//end class

Listing 8 also signals the end of the class and the end of the discussion on
GwtApp011.

An API map of the GWT

This will probably be a good place to introduce you to a very interesting
article that I discovered on the web.  Figure 4 shows a greatly reduced
version of a visual map that illustrates the relationships among the various
classes in the GWT API.  If like me, you are having difficulty keeping the
organization of the GWT API straight in your mind, this map may be helpful.


Figure 4. An API map of the GWT.

Obviously, the map in Figure 4 is too small to be legible.  However, you
will find a full-size copy of the map in the article named GWT API Map in
Resources.

GwtApp012 – MouseListener

A screen shot at startup

This application demonstrates all five methods declared in the
MouseListener
interface.

Figure 5 shows a screen shot of the application when it first starts running. 
The various labels are displaying their default or startup values in Figure 5.


Figure 5. A screen shot at startup.

A screen shot while the application is running

The text at the top of Figure 5 describes the purpose of each of the seven
labels.  Basically, they are used to display the results of various
manipulations of the mouse that involve pressing and releasing the buttons on
the mouse and moving the mouse within the blank area (a FocusPanel
object)
between the labels.

Figure 6 shows the state of the GUI after the user has moved the mouse within
that blank area and has pressed and released a mouse button within that area.


Figure 6. A screen shot while the application is
running.

Because this application is very dynamic, you really need to compile and run
the application in order to get a good feel for what the various numbers in
Figure 6 mean.

Description of the application

The purpose of this application is to demonstrate the behavior of all five
methods declared in the MouseListener interface.  Seven Label
objects and a FocusPanel object are placed in a DockPanel object
as shown in Figure 5.

Four labels are placed in the NORTH location of the DockPanel and three labels are placed in
the SOUTH location.  These labels are used to display the output produced
by the five mouse listener methods when the mouse is manipulated inside and
outside of the FocusPanel, which is placed in the CENTER of the
DockPanel
object.

Manipulating the mouse buttons and moving the mouse
pointer

The four labels in the NORTH show the results of manipulating any of the
three mouse buttons.  The three labels in the SOUTH show the results of
moving the mouse pointer.

Pressing and releasing mouse buttons

The top two labels in the NORTH location show the X and Y coordinates where a
mouse button is pressed within the FocusPanel object.  The bottom
two labels in the NORTH location show the X and Y coordinates where a mouse
button is released within the FocusPanel object.

Are you in or out?

The top label in the SOUTH location shows whether the mouse pointer is In
or Out of the area occupied by the FocusPanel object.

Tracking the mouse pointer motion

The bottom two labels in the SOUTH location display X and Y coordinate values
that track the movement of the mouse pointer while it is in the FocusPanel.

Testing the application

The application was tested using J2SE 5.0, GWT version 1.2.22, and
jakarta-tomcat-5.0.27 running as a localhost server under WinXP.

Will discuss in fragments

As mentioned earlier, a complete listing of the HTML host page for this application is
provided in one of the listings near the end of the lesson.  There is nothing new
in that host page, so I won’t discuss it further.

A complete listing of the Java code for the application is also provided in
one of the listings near the end of the lesson. 
As usual, I will discuss this code in fragments.  The first fragment is
shown in Listing 9.

Beginning of the class definition for GwtApp012

Listing 9 shows the beginning of the class definition, the beginning of the
onModuleLoad method, and the instantiation of the DockPanel object
as well as the instantiation of the seven Label objects.


Listing 9. Beginning of the class definition for
GwtApp012.

package GwtApp.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.*;

public class GwtApp012 implements EntryPoint{

  //This is the entry point method.
  public void onModuleLoad(){

    //Instantiate a DockPanel object.
    final DockPanel dockPanel = new DockPanel();
    
    //Instantiate the Label objects.
    final Label labelXdown = new Label("X-down");
    final Label labelYdown = new Label("Y-down");
    
    final Label labelXup = new Label("X-up");
    final Label labelYup = new Label("Y-up");
    
    final Label labelXmove = new Label("X-move");
    final Label labelYmove = new Label("Y-move");
    
    final Label labelInOut = new Label("Out");

There is nothing new in Listing 9, so I won’t discuss it further.

Instantiate the FocusPanel object and set its size

Listing 10 instantiates and sets the size of the FocusPanel object to
a width of 100 pixels and a height of 50 pixels.


Listing 10. Instantiate the FocusPanel object and set its size.

    final FocusPanel focusPanel = new FocusPanel();
    focusPanel.setWidth("100px");
    focusPanel.setHeight("50px");

Other than the fact that I probably haven’t used a FocusPanel object
in a previous application, there is nothing new or unusual in Listing 10. 
Therefore, I won’t discuss it further.

Register a MouseListener object

Listing 11 shows the beginning of the code necessary to use an anonymous
class to register an anonymous
MouseListener object on the FocusPanel object.


Listing 11. Register a MouseListener object.

    focusPanel.addMouseListener(
      new MouseListener(){
        public void onMouseDown(Widget sender,int x,int y){
          labelXdown.setText("X-down = " + x);
          labelYdown.setText("Y-down = " + y);
        }//end onMouseDown

As I mentioned earlier, the MouseListener interface declares the
following five methods:

  • onMouseDown
  • onMouseUp
  • onMouseEnter
  • onMouseLeave
  • onMouseMove

The cardinal rule of interface implementation

As you should already know, whenever a Java class implements an interface, it
must override and provide concrete definitions for all of the methods declared
in the interface.  (In case you didn’t already know that, you may want
to do some background studying at
http://www.dickbaldwin.com/toc.htm
.)

Incoming parameter number and types

A MouseEvent object
All of the standard Java mouse event handlers receive a reference to an object
of type MouseEvent, which encapsulates
either eight or nine different pieces of information, depending on which
overloaded constructor was used to construct the object.

A major difference between the GWT and standard Java has to do with the numbers
and types of incoming parameters to the event handler methods that are declared
in the listener interfaces.

For the GUI
components, standard Java receives a single parameter that refers to an object. 
All of the information that is passed to the event handler method is
encapsulated in the object.

Different numbers and types of parameters

For the GWT, the different event handler methods may receive different
numbers and types of parameters.  For example, each of the mouse event
handlers receives an incoming parameter that is a reference to an object of type
Widget.  However, some but not all of the handlers also receive two
additional parameters of type int that indicate the location of the mouse
pointer when the event happened.

Which mouse button was pressed?
As near as I can tell, it is not possible to differentiate between the
different mouse buttons with the GWT.  However, information identifying
the specific mouse button that was pressed is available for mouse events in
standard Java.

The code in Listing 11 ignores the first incoming parameter, but uses the
other two incoming parameters to display the x and y coordinates of the location
of the mouse pointer within the FocusPanel of Figure 6 when the mouse button was pressed.

The onMouseUp method

In keeping with the Cardinal Rule of interface implementation, Listing
12 defines the interface method named onMouseUp.


Listing 12. The onMouseUp method.

        public void onMouseUp(Widget sender,int x,int y){
          labelXup.setText("X-up = " + x);
          labelYup.setText("Y-up = " + y);
        }//end onMouseUp

The event handler in Listing 12 is similar to the event handler in Listing
11.  This method will be executed each time the user releases the mouse
button while the mouse pointer is within the area of the FocusPanel in
Figure 6.

The remaining three interface methods

Listing 13 shows the concrete definitions for the remaining three methods
that are declared in the GWT MouseListener interface.


Listing 13. The remaining three interface methods.

        public void onMouseEnter(Widget sender){
          labelInOut.setText("In");
        }//end onMouseLeave
        
        public void onMouseLeave(Widget sender){
          labelInOut.setText("Out");
        }//end onMouseLeave
        
        public void onMouseMove(Widget sender,int x,int y){
          labelXmove.setText("X-move = " + x);
          labelYmove.setText("Y-move = " + y);
        }//end onMouseMove     
        
      }//end constructor
    );//end addMouseListener

In or out of the FocusPanel

The first two methods in Listing 13 are executed when the mouse pointer
enters and leaves the area occupied by the FocusPanel object in Figure 6. 
These two methods display text that indicates whether the mouse pointer is
inside of or outside of the area of the FocusPanel.

Track the location of the mouse pointer

The third method in Listing 13 is executed repeatedly as the user moves the
mouse pointer within the area of the FocusPanel in Figure 6.  This
causes the two bottom labels in Figure 6 to continuously display the coordinates
of the mouse pointer within the FocusPanel as the mouse pointer is moved
within that panel.

End of the anonymous class definition

Listing 13 also signals the end of the anonymous class definition for this
application.

The remaining Java code for GwtApp012

Listing 14 shows the remaining Java code for the web application named
GwtApp012.


Listing 14. The remaining Java code for GwtApp012.

    //Expose the border for each cell in the DockPanel.
    dockPanel.setBorderWidth(5);
    
    //Add the components to the DockPanel.
    dockPanel.add(labelXdown, DockPanel.NORTH);
    dockPanel.add(labelYdown, DockPanel.NORTH);
    dockPanel.add(labelXup, DockPanel.NORTH);
    dockPanel.add(labelYup, DockPanel.NORTH);
    
    dockPanel.add(labelYmove, DockPanel.SOUTH);
    dockPanel.add(labelXmove, DockPanel.SOUTH);
    
    dockPanel.add(labelInOut, DockPanel.SOUTH);
    
    dockPanel.add(focusPanel, DockPanel.CENTER);
    
    //Add the panel to the browser window.
    RootPanel.get().add(dockPanel);
    
  }//end onModuleLoad method
}//end class

You have seen code like that shown in Listing 14 in earlier examples in this
and the previous tutorial lessons in this series.  Therefore, no further explanation of the
code in Listing 14 should be necessary.


GwtApp013 – KeyboardListener, LoadListener, and ScrollListener

A screenshot at program startup

This application illustrates KeyboardListener, LoadListener, and
ScrollListener event handling.

The application places a TextBox, a ScrollPanel, and two
Label
objects in a DockPanel object as shown in Figure 7.


Figure 7. Screenshot at startup for GwtApp013.

Default values at startup

Note that the name of a default image file is entered into the text box at
startup for convenience, but the text box could just as well have been left
empty.

Also note the text in the two bottom labels below the scroll panel. 
These labels are used to report information to the user during operation. 
You will see information displayed in these labels in Figures 8 through 10 below.

Registration of KeyboardListener and ScrollListener
objects

This application registers a KeyboardListener object on the TextBox
When the user types an image file name into the text box and presses the Enter
key, this event handler attempts to load the image file and to place the image
in the ScrollPanel.

The application also registers a ScrollListener object on the
ScrollPanel
to report on the positions of the sliders when the user scrolls
the image in the ScrollPanel.

A screenshot of the scrolled pool image

Figure 8 shows the result of:

  • Causing the text box to gain the focus
  • Accepting the name of the default image file placed in the text box at
    startup (or typing the filename pool.jpg into the text box)
  • Pressing the Enter key
  • Scrolling the image about half way to the right and about half way down


Figure 8. A screenshot of the scrolled pool image.

As you can see, the image of the swimming pool is shown scrolled to the right
and down.  Also, the label immediately below the scroll panel displays the
scrolling position and the bottom label indicates that the image was
successfully loaded.  (I will have more to say about the image loading
process later.)

A screenshot of the books image

Figure 9 shows the result of:

  • Typing the name of a different image file into the text box and pressing
    the Enter key
  • Scrolling the image all the way to the right and all the way down


Figure 9. Screenshot of the scrolled book image.

The image of the shelves containing books is shown scrolled all the way to
the right and down.  As before, the label immediately below the scroll panel
displays the scrolling position and the bottom label indicates that the image
was successfully loaded.

A screenshot for an invalid image file name

Now, let’s get back to the process of loading the image.  This application registers a LoadListener object on the Image
object to report on the success or failure of loading the image file. 
Figure 10 shows the result of typing an invalid image file name into the text
box and pressing the Enter key.


Figure 10. Screenshot for an invalid image file name.

As you can see, the scroll panel in Figure 10 doesn’t contain an image. 
In addition, the load listener caused the bottom label in Figure 10 to report that an
error occurred while attempting to load the image.

Program testing

This application was tested using J2SE 5.0, GWT version 1.2.22, and
jakarta-tomcat-5.0.27 running as a localhost server under WinXP.

Beginning of the class definition for GwtApp013

Listing 15 shows the beginning of the class definition for GwtApp013.


Listing 15. Beginning of class definition for GwtApp013.

package GwtApp.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.*;

public class GwtApp013 implements EntryPoint{

  //This is the entry point method.
  public void onModuleLoad(){
    final Image image = new Image();

Listing 15 instantiates an Image object that will be used to receive
the contents of an image file.  Otherwise, there is nothing new in Listing
15.

Finish constructing the GUI.

Listing 16 contains all of the code necessary to finish constructing the GUI
shown in Figure 7.


Listing 16. Finish constructing the GUI.

    //Instantiate a DockPanel object for the main display.
    final DockPanel dockPanel = new DockPanel();
    
    //Instantiate a TextBox object for entry of the image
    // file name and add it to the DockPanel in the NORTH
    // location.
    TextBox fileName = new TextBox();
    fileName.setVisibleLength(46);
    fileName.setText("pool.jpg");//set to default file
    dockPanel.add(fileName,DockPanel.NORTH);
    
    //Instantiate a Label object for display of the image
    // loading status and add it to the DockPanel in the
    // SOUTH location.
    final Label status = new Label(
                           "Load status will appear here");
    dockPanel.add(status,DockPanel.SOUTH);
    
    //Instantiate a Label object for display of the
    // scrolling information and add it to the DockPanel
    // also in the SOUTH location.
    final Label scrollDisplay = new Label(
                      "Scroll position will appear here.");
    dockPanel.add(scrollDisplay,DockPanel.SOUTH);

    //Instantiate a ScrollPanel object to contain the
    // image and add it to the CENTER of the DockPanel.
    // The height and width is controlled by the CSS
    // information in the host page.
    final ScrollPanel scrollPanel = new ScrollPanel();
    scrollPanel.setStyleName("scrollPanel");
    dockPanel.add(scrollPanel,DockPanel.CENTER);

You have seen most of the code in Listing 16 earlier in this lesson, or in earlier lessons
in this series.  Even
the code that you haven’t seen before is straightforward Java programming code, and
shouldn’t require an explanation beyond the embedded comments.

A KeyboardListener object

Extend an adapter class
Note that this syntax extends an adapter class and overrides the onKeyPress
method instead of implementing an interface.  (See the link to the
earlier lesson named "The Essence of OOP using Java, Anonymous Classes" in
Resources for more information on anonymous inner
classes.)

The code in Listing 17 defines an anonymous class, and also instantiates and registers an anonymous
KeyboardListener
object on the text field used for entry of the image file
name.

Loading the image file

This event handler tries to load the
image when the user presses the Enter key after typing in the file name.


Listing 17. Register a KeyboardListener object.

    fileName.addKeyboardListener(
      new KeyboardListenerAdapter(){
        public void onKeyPress(
                 Widget sender,char keyCode,int modifiers){
          if(keyCode == KeyboardListener.KEY_ENTER){
            //Clear the old image from the ScrollPanel
            scrollPanel.clear();
            //Start loading the new image.
            image.setUrl(((TextBox)sender).getText());
            //Now add the image to the ScrollPanel.
            scrollPanel.add(image);
          }//end if
        }//end onKeyPress
      }//end constructor
    );//end addKeyboardListener

The setUrl method

Unfortunately, the GWT documentation for the Image class for GWT
version 1.2.22 is fairly
sparse.  I was able to determine experimentally that
invoking the method named setUrl on the Image object causes the process of loading the
specified image file into the Image object to begin.

Monitor the loading of the image file

The code in Listing 18 instantiates and registers a LoadListener object to
monitor the loading of the image file and to report on the success or failure of
that operation.


Listing 18. A listener to monitor the loading of the image file.

    image.addLoadListener(
      new LoadListener(){
        public void onLoad(Widget sender){
          status.setText("Image load complete.");
        }//end onLoad
      
        public void onError(Widget sender){
          status.setText(
             "An error occurred while loading the image.");
          //Reset the scrolling info to its original value.
          scrollDisplay.setText(
                      "Scroll position will appear here.");
        }//end onError
      }//end constructor
    );//end addLoadListener

Two interface methods

As you can see in Listing 18, the LoadListener interface declares two
methods.  One is executed when the contents of the image file complete the
load process.  The other is executed if there is an error in the attempt to
load the contents of the image file.

The results of the execution of onLoad method are shown in the bottom
label in Figure 8
and Figure 9.  The result of the execution of the onError method
is shown in Figure 10, which attempted to load an image from an invalid file
name.

Register a ScrollListener object

Listing 19 instantiates and registers a ScrollListener object to report on the scrolling status, in terms of the distances of the sliders from the top and the left side.


Listing 19. Register a ScrollListener object.

    scrollPanel.addScrollListener(
      new ScrollListener(){
        public void onScroll(
               Widget sender,int scrollLeft,int scrollTop){
          scrollDisplay.setText("Scroll: Left = " 
                    + scrollLeft + ", Top = " + scrollTop);
        }//end onScroll
      }//end constructor
    );//end addScrollListener

    //Add the DockPanel to the browser window.
    RootPanel.get().add(dockPanel);
    
  }//end onModuleLoad method
}//end class
Scroll position continuously updated
If you execute this application, you will see that the scroll position is
continuously updated as the scrolling of the image progresses.

The onScroll method in Listing 19 is executed whenever the user scrolls
the image vertically or horizontally.  The results are shown in the label
immediately below the scroll panel in Figure 8 and Figure 9.

The end of the class

Listing 19 also adds the DockPanel object to the browser window and signals the end of the class for
GwtApp013.  Therefore, this completes the discussion of the
application named GwtApp013.

GwtApp014 – WindowResizeListener

A screenshot at startup

The purpose of this application is to demonstrate the use of the
WindowResizeListener
interface to monitor and display the size of the
browser window.

The application places a Label object in the browser window that
displays the initial size of the browser window, and is used later to display
the new size of the browser window when the browser is manually resized by the
user.

Figure 11 shows a screenshot of the application GUI at startup.


Figure 11. Application GwtApp014 at startup.

As you can see, this screenshot displays the width and height of the browser
window when the application first starts running.

Register a WindowResizeListener object

The application uses a static method of the Window class to register a
listener object of type WindowResizeListener on the browser window. 
This is a little unusual, because the registration methods are not typically
static methods.  Rather they are usually instance methods.  This makes
it possible to register different
listeners on different GUI objects instantiated from the same class. 
However, there can be only one Window object in a GWT application. 
The Window object occupies the
client area of the browser.  Therefore, it is acceptable in this case for
the registration method to be a static method.

Display the initial size of the browser window

The application also uses static methods of the Window class to get
and to display the
initial size of the browser window as shown in Figure 11.

Implement the WindowResizeListener interface

Not an anonymous class
Note that although this listener class instantiates an anonymous object from
an inner class, it does not use an anonymous inner class.

The application defines a class that implements the WindowResizeListener
as an inner class to make it easy for the event
handler method to access the label in order to display the size.  The application then registers an
object of this class on the browser window as described above.

Display the new size of the browser window

When the user resizes the browser, the event handler displays the new width
and height of the browser window in the label as shown in Figure 12.


Figure 12. Display the new size of the browser window.

Application testing

The application was tested using J2SE 5.0, GWT version 1.2.22, and
jakarta-tomcat-5.0.27 running as a localhost server under WinXP.

Beginning of the GwtApp014 class

Listing 20 shows the beginning of the GwtApp014 class and the
onModuleLoad
method in its entirety.


Listing 20. Beginning of the GwtApp014 class.

package GwtApp.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.user.client.*;

public class GwtApp014 implements EntryPoint{

  Label label = new Label("");//Display window size here.

  //This is the entry point method.
  public void onModuleLoad(){
    //Instantiate an anonymous listener object from an
    // inner listener class and register it on the window.
    Window.addWindowResizeListener(new WinResizeLstnr());
    
    //Display the initial size of the browser window in
    // the label.
    label.setText("Initial size is " 
                               + Window.getClientWidth() 
                               + " x " 
                               + Window.getClientHeight());

    //Add the label to the browser window.
    RootPanel.get().add(label);
  }//end onModuleLoad method

Given the earlier description, the code in Listing 20 is straightforward and
should not require any explanation beyond the embedded comments.

The inner listener class definition

Listing 21 shows the definition of the inner listener class in its entirety. 
I made this an inner class so that an object of the class will have direct access to the label in order to display the new width and height of the browser window.


Listing 21. The inner listener class definition for GwtApp014.

  class WinResizeLstnr implements WindowResizeListener{
    public void onWindowResized(int width,int height){
      label.setText(
                   "Resized to " + width + " x " + height);
    }//end onWindowResized
  }//end class WinResizeLstnr

}//end class GwtApp014

The code in Listing 21 is also straightforward.  When the user manually
resizes the browser window, the onWindowResized method is executed, which
displays the new size in the label.  Otherwise, Listing 21 should not
require any explanation beyond the embedded comments.

Operational difference between IE 6 and Firefox

I did notice an interesting aspect of the operation of this application,
which differs between IE 6 and Firefox.  When the application is executed
in IE 6 and the user manually resizes the browser by dragging the corner of the
browser with the mouse, the contents of the label continuously change to track
the current size of the browser window.  This suggests that IE 6 fires a
stream of events causing the method named onWindowResized in Listing 21
to be executed over and over.

However, with Firefox, the contents of the label don’t change until the user
stops dragging the corner of the browser, at which time the values for the
current size are displayed.  This suggests that Firefox fires a single
event when the user stops dragging the corner of the browser.  This causes
the method named onWindowResized in Listing 21 to be executed once in
order to display the new size of the browser.

End of the class

Listing 21 also signals the end of the GwtApp014 class and the end of
the discussion for this application.

GwtApp015 – WindowCloseListener

Purpose and behavior of the application

The purpose of this application is to demonstrate the use of the
WindowCloseListener
interface to display a confirmation dialog when the user
attempts to close the browser window or to navigate to a different site.

The application uses a static method of the Window class to register a
listener object of type WindowCloseListener on the browser window.

Define an inner listener class

The application defines a class that implements the WindowCloseListener
as an inner class.  Then the application registers an object of this class
on the browser window as described above.

Figure 13 shows the application GUI at startup.


Figure 13. GwtApp015 application GUI at startup.

As you can see, this GUI isn’t very interesting, because the application
doesn’t do anything other than to provide the demonstration described above. 
What is more interesting is the confirmation dialog shown in Figure 14.

The confirmation dialog

When the user attempts to close the browser or to navigate to a different site,
the event handler returns a string that is embedded into a confirmation dialog
that asks the user whether or not she wishes to navigate away from the page.

For example, Figure 14 shows the result of my having typed www.google.com
into the address field of the browser shown in Figure 13 and then pressing the
Enter key.


Figure 14. The confirmation dialog for GwtApp015.

As you will see later, the phrase in the middle of Figure 14 was embedded
into the dialog by the code in this application.

Application testing

The application was tested using J2SE 5.0, GWT version 1.2.22, and
jakarta-tomcat-5.0.27 running as a localhost server under WinXP.

The onModuleLoad method

Listing 22 shows the beginning of the GwtApp015 class, along with the
onModuleLoad method in its entirety.


Listing 22. The beginning of the GwtApp015 class.

package GwtApp.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.user.client.*;

public class GwtApp015 implements EntryPoint{

  //This is the entry point method.
  public void onModuleLoad(){
    //Instantiate an anonymous listener object from an
    // inner listener class and register it on the window.
    Window.addWindowCloseListener(new WinCloseLstnr());
  }//end onModuleLoad method

Listing 22 shouldn’t require an explanation because it doesn’t contain
anything that is new to this application.

Beginning of the WinCloseLstnr class

The WinCloseLstnr class implements the WindowCloseListener
interface, which declares the following two methods:

  • onWindowClosing
  • onWindowClosed

Listing 23 shows the beginning of the WinCloseLstnr class along with
the complete definition of the method named onWindowClosing.


Listing 23. Beginning of the WinCloseLstnr class.

  //This is a listener class that is defined as an inner
  // class.
  class WinCloseLstnr implements WindowCloseListener{
    
    public java.lang.String onWindowClosing(){
      return "Msg from your WindowCloseListener";
    }//end onWindowClosing

What does Google have to say?

Here is a paraphrased version of some of what the GWT documentation has to
say about this method.

Fired (invoked) just before the browser window closes or navigates to
a different site.  No user-interface may be displayed during shutdown.
Returns non-null to present a confirmation dialog that asks the user whether
or not she wishes to navigate away from the page.  The string returned
will be displayed in the close confirmation dialog box.

As you can see, the string that is returned in Listing 23 was displayed in
Figure 14.

The onWindowClosed method

Listing 24 shows the definition of the method named onWindowClosed.  The method is empty
in this application, and therefore is of no consequence in the behavior of the application.


Listing 24. The onWindowClosed method.

    public void onWindowClosed(){
      //empty method
    }//end onWindowClosed
      
  }//end class WinCloseLstnr

}//end class GwtApp015

What does Google have to say?

Here is some of what the GWT documentation has to say about the behavior
of this method:

Fired (invoked) after the browser window closes or navigates to a
different site. This event cannot be cancelled, and is used mainly to clean
up application state and/or save state to the server.

You can take that for what it’s worth.

End of the class

Listing 24 signals the end of the GwtApp015 class, and the end of the
discussion of the GwtApp015 application.

Run the programs

I encourage you to copy the code from Listing 25 through Listing 34 into your text
editor, compile it, and execute it.  Experiment with the different
applications, making
changes to them, and observing the results of your changes.

Learn how to write web applications using this exciting new technology. Above
all, enjoy the process. Programming can be fun.

Summary

I began by describing how to upgrade from version 1.1.10 to version 1.2.22 of
the GWT.  Along the way, I described some important attributes of the new
version.

Then I taught you how to write the Java code necessary to accomplish event
driven programming using the GWT, and illustrated that process with five
different web applications that demonstrate how to program for seven of the fifteen
different event types supported by the GWT.

What’s next?

Future lessons will concentrate on the Java programming techniques required
to produce rich Ajax web applications using the GWT framework.  This will
include discussions and explanations of such issues as the available GWT user
interface components, possibly some more on event-driven programming using the
GWT, possibly some more on styling, possibly something about drag-and-drop, and
a little about Remote Procedure Calls with the GWT.

At this point, I’m not certain what the order of the topics in above list
will be, but I have decided that the next lesson will concentrate on focus
events, click events, and drag-and-drop.

Complete program listings


Complete listings of the applications discussed in this lesson are shown in
Listing 25 through Listing 34 below.
 


Listing 25. Host page for GwtApp011.

<!---------------------------------------------------------
File GwtApp010.html
GWT host page.
Revised: 1/18/06
---------------------------------------------------------->
<html>
<head>
<title>Wrapper HTML for GwtApp010</title>
<meta name='gwt:module' content='GwtApp.GwtApp010'>
</head>

<body>
<script language="javascript" src="gwt.js"></script>
<iframe id="__gwt_historyFrame" 
                style="width:0;height:0;border:0"></iframe>

<h3>GwtApp010</h3>
<p>
This is a replica of the application named GwtApp005 from 
an earlier lesson. The purpose of this application is to 
determine if the upgrade to version 1.2.22 resolved the 
symmetry problem at the bottom of a DockPanel object. As 
you can see from the following image, the upgrade did not 
resolve the problem.
</p>

</body>
</html>


Listing 26. Java code for GwtApp011.

/*File GwtApp011.java
Copyright 2006, R.G.Baldwin

The purpose of this application is to illustrate the use of
the ChangeListener interface to register and service events
on a ListBox component.

Two ListBox objects and one Label object are placed in a
HorizontalPanel object.  One ListBox is completely open and
the other is a drop down ListBox.  The two ListBox objects
are populated with strings and a unique name is assigned to
each ListBox.

An anonymous ChangeListener object is registered on each
ListBox.  When the user selects a new item in either 
ListBox, the name of the ListBox and the selected item are
displayed in the Label.  (At startup, the Label displays
the word "Empty.")

Note that I tried unsuccessfully to get the ChangeListener
to work with a TextBox.  It seems to work in the compiled
version with Firefox, but doesn't seem to work properly
in hosted mode.  In that situation, the TextBox fires an
event when you press the Enter key after having modified
the contents of the TextBox.  However, even the compiled 
version doesn't seem to work properly with IE 6.x.

Tested using J2SE 5.0, GWT version 1.2.22, and 
jakarta-tomcat-5.0.27 running as a localhost server
under WinXP.
**********************************************************/

package GwtApp.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.*;

public class GwtApp011 implements EntryPoint{

  //This is the entry point method.
  public void onModuleLoad(){

    //Instantiate a Label object that will be used to
    // display the output text produced by the event
    // handlers.
    final Label label = new Label("Empty");

    //Instantiate and populate a ListBox object.
    final ListBox listBoxA = new ListBox();
    listBoxA.setVisibleItemCount(4);
    listBoxA.addItem("Bill");
    listBoxA.addItem("Tom");
    listBoxA.addItem("Sue");
    listBoxA.addItem("Joe");
    listBoxA.setName("Open ListBox");
    
    //Register an anonymous ChangeListener object on the
    // ListBox object.
    listBoxA.addChangeListener(
      new ChangeListener(){
        public void onChange(Widget sender){
          ListBox listBox = (ListBox)sender;
          String listBoxName = listBox.getName();
          int index = listBox.getSelectedIndex();
          String itemText = listBox.getItemText(index);
          label.setText(listBoxName + ": " + itemText);
        }//end onChange
      }//end constructor
    );//end addChangeListener
    
    //Instantiate, populate, and register a ChangeListener
    // on another ListBox object.
    final ListBox listBoxB = new ListBox();
    listBoxB.addItem("Spot");
    listBoxB.addItem("Fido");
    listBoxB.addItem("Butch");
    listBoxB.addItem("Scotty");
    listBoxB.setName("Drop Down ListBox");
    
    listBoxB.addChangeListener(
      new ChangeListener(){
        public void onChange(Widget sender){
          ListBox listBox = (ListBox)sender;
          String listBoxName = listBox.getName();
          int index = listBox.getSelectedIndex();
          String itemText = listBox.getItemText(index);
          label.setText(listBoxName + ": " + itemText);
        }//end onChange
      }//end constructor
    );//end addChangeListener
    
    //Instantiate a HorizontalPanel object and populate it
    // with the two ListBox objects and the Label object.
    HorizontalPanel horizPanel = new HorizontalPanel();
    horizPanel.setSpacing(5);
    horizPanel.add(listBoxA);
    horizPanel.add(listBoxB);
    horizPanel.add(label);
    
    //Add the horizontal panel to the browser window.
    RootPanel.get().add(horizPanel);
    
  }//end onModuleLoad method
}//end class


Listing 27. Host page for GwtApp012.

<!---------------------------------------------------------
File GwtApp012.html
GWT host page.
Revised: 1/18/06
---------------------------------------------------------->
<html>
<head>
<title>Wrapper HTML for GwtApp012</title>
<meta name='gwt:module' content='GwtApp.GwtApp012'>
</head>

<body>
<script language="javascript" src="gwt.js"></script>
<iframe id="__gwt_historyFrame" 
                style="width:0;height:0;border:0"></iframe>

<h3>GwtApp012</h3>

<p>Demonstrates behavior of all five methods of the 
MouseListener interface.</p>
<ul>
<li>Labels display output produced by the methods.</li>
<li>Top labels show coordinates where a mouse button is 
pressed or released within the center panel.</li>
<li>Top label at the bottom shows whether the mouse pointer 
is In or Out of the center panel.</li>
<li>Bottom two labels show coordinate values that track the 
movement of the mouse pointer within the center panel.</li>
</ul>

</body>
</html>


Listing 28. Java code for GwtApp012.

/*File GwtApp012.java
Copyright 2006, R.G.Baldwin

The purpose of this application is to demonstrate the 
behavior of all five methods declared in the MouseListener 
interface.

Seven Label objects and a FocusPanel object are placed in 
a DockPanel object. Four labels are placed in the NORTH 
location and three labels are placed in the SOUTH 
location. These labels are used to display the output 
produced by the five mouse listener methods when the mouse 
is manipulated inside and outside of the FocusPanel, which 
is placed in the CENTER of the DockPanel object.

The four labels in the NORTH show the results of 
manipulating any of the three mouse buttons. The three 
labels in the SOUTH show the results of moving the mouse 
pointer.

The top two labels in the NORTH location show the X and Y 
coordinates where a mouse button is pressed while in the
FocusPanel object. The bottom two labels in the NORTH 
location show the X and Y coordinates where a mouse button 
is released while in the FocusPanel object.

The top label in the SOUTH location shows whether the 
mouse pointer is In or Out of the FocusPanel object.

The bottom two labels in the SOUTH location display X and 
Y coordinate values that track the movement of the mouse 
pointer while it is in the FocusPanel.

Tested using J2SE 5.0, GWT version 1.2.22, and 
jakarta-tomcat-5.0.27 running as a localhost server
under WinXP.
**********************************************************/

package GwtApp.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.*;

public class GwtApp012 implements EntryPoint{

  //This is the entry point method.
  public void onModuleLoad(){

    //Instantiate a DockPanel object.
    final DockPanel dockPanel = new DockPanel();
    
    //Instantiate the Label objects.
    final Label labelXdown = new Label("X-down");
    final Label labelYdown = new Label("Y-down");
    
    final Label labelXup = new Label("X-up");
    final Label labelYup = new Label("Y-up");
    
    final Label labelXmove = new Label("X-move");
    final Label labelYmove = new Label("Y-move");
    
    final Label labelInOut = new Label("Out");
    
    //Instantiate the FocusPanel object and set its size.
    final FocusPanel focusPanel = new FocusPanel();
    focusPanel.setWidth("100px");
    focusPanel.setHeight("50px");

    //Register an anonymous MouseListener object on the
    // FocusPanel object.
    focusPanel.addMouseListener(
      new MouseListener(){
        public void onMouseDown(Widget sender,int x,int y){
          labelXdown.setText("X-down = " + x);
          labelYdown.setText("Y-down = " + y);
        }//end onMouseDown
        
        public void onMouseUp(Widget sender,int x,int y){
          labelXup.setText("X-up = " + x);
          labelYup.setText("Y-up = " + y);
        }//end onMouseUp
        
        public void onMouseEnter(Widget sender){
          labelInOut.setText("In");
        }//end onMouseLeave
        
        public void onMouseLeave(Widget sender){
          labelInOut.setText("Out");
        }//end onMouseLeave
        
        public void onMouseMove(Widget sender,int x,int y){
          labelXmove.setText("X-move = " + x);
          labelYmove.setText("Y-move = " + y);
        }//end onMouseMove     
        
      }//end constructor
    );//end addMouseListener

    //Expose the border for each cell in the DockPanel.
    dockPanel.setBorderWidth(5);
    
    //Add the components to the DockPanel.
    dockPanel.add(labelXdown, DockPanel.NORTH);
    dockPanel.add(labelYdown, DockPanel.NORTH);
    dockPanel.add(labelXup, DockPanel.NORTH);
    dockPanel.add(labelYup, DockPanel.NORTH);
    
    dockPanel.add(labelYmove, DockPanel.SOUTH);
    dockPanel.add(labelXmove, DockPanel.SOUTH);
    
    dockPanel.add(labelInOut, DockPanel.SOUTH);
    
    dockPanel.add(focusPanel, DockPanel.CENTER);
    
    //Add the panel to the browser window.
    RootPanel.get().add(dockPanel);
    
  }//end onModuleLoad method
}//end class


Listing 29. Host page for GwtApp013.

<!---------------------------------------------------------
File GwtApp013.html
GWT host page.
Revised: 11/18/06
---------------------------------------------------------->
<html>
<head>
<title>Wrapper HTML for GwtApp013</title>
<meta name='gwt:module' content='GwtApp.GwtApp013'>
<style>
  .scrollPanel{
    height: 200px;
    width: 300px;
    border: 1px solid DARKBLUE;
    padding: 4px;
  }
</style>
</head>

<body>
<script language="javascript" src="gwt.js"></script>
<iframe id="__gwt_historyFrame" 
              style="width:0;height:0;border:0"></iframe>

<h3>GwtApp013</h3>

<p>Demonstrates keyboard, load, and scroll events.</p>
Enter name of image file below.

</body>
</html>


Listing 30. Java code for GwtApp013.

/*File GwtApp013.java
Copyright 2006, R.G.Baldwin

Illustrates keyboard, load, and scroll event handling.

Places a TextBox, a ScrollPanel, and two Label objects in
a DockPanel.

Registers a KeyboardListener on the TextBox.  When the
user types an image file name and presses the Enter key,
this event handler attempts to load the image file and
place the image in the ScrollPanel.

Registers a LoadListener on the Image object to report
on the success or failure of loading the image file.

Registers a ScrollListener on the ScrollPanel to report
on the positions of the sliders when the user scrolls the
image in the ScrollPanel.

Tested using J2SE 5.0, GWT version 1.2.22, and 
jakarta-tomcat-5.0.27 running as a localhost server
under WinXP.
**********************************************************/

package GwtApp.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.*;

public class GwtApp013 implements EntryPoint{

  //This is the entry point method.
  public void onModuleLoad(){
    //Instantiate an Image object to receive the contents
    // of an image file.
    final Image image = new Image();
    
    //Instantiate a DockPanel object for the main display.
    final DockPanel dockPanel = new DockPanel();
    
    //Instantiate a TextBox object for entry of the image
    // file name and add it to the DockPanel in the NORTH
    // location.
    TextBox fileName = new TextBox();
    fileName.setVisibleLength(46);
    fileName.setText("pool.jpg");//set to default file
    dockPanel.add(fileName,DockPanel.NORTH);
    
    //Instantiate a Label object for display of the image
    // loading status and add it to the DockPanel in the
    // SOUTH location.
    final Label status = new Label(
                           "Load status will appear here");
    dockPanel.add(status,DockPanel.SOUTH);
    
    //Instantiate a Label object for display of the
    // scrolling information and add it to the DockPanel
    // also in the SOUTH location.
    final Label scrollDisplay = new Label(
                      "Scroll position will appear here.");
    dockPanel.add(scrollDisplay,DockPanel.SOUTH);

    //Instantiate a ScrollPanel object to contain the
    // image and add it to the CENTER of the DockPanel.
    // The height and width is controlled by the CSS
    // information in the host page.
    final ScrollPanel scrollPanel = new ScrollPanel();
    scrollPanel.setStyleName("scrollPanel");
    dockPanel.add(scrollPanel,DockPanel.CENTER);

    //Instantiate and register an anonymous
    // KeyboardListener on the text field used for entry of
    // the image file name.  Note that this syntax extends
    // an adapter class and overrides the onKeyPress method 
    // instead of implementing an interface. This
    // event handler tries to load the image when the user
    // presses the Enter key after typing in the file name.
    fileName.addKeyboardListener(
      new KeyboardListenerAdapter(){
        public void onKeyPress(
                 Widget sender,char keyCode,int modifiers){
          if(keyCode == KeyboardListener.KEY_ENTER){
            //Clear the old image from the ScrollPanel
            scrollPanel.clear();
            //Start loading the new image.
            image.setUrl(((TextBox)sender).getText());
            //Now add the image to the ScrollPanel.
            scrollPanel.add(image);
          }//end if
        }//end onKeyPress
      }//end constructor
    );//end addKeyboardListener

    //Instantiate and register a LoadListener object to
    // report on the success or failure of loading the
    // contents of the image file.
    image.addLoadListener(
      new LoadListener(){
        public void onLoad(Widget sender){
          status.setText("Image load complete.");
        }//end onLoad
      
        public void onError(Widget sender){
          status.setText(
             "An error occurred while loading the image.");
          //Reset the scrolling info to its original value.
          scrollDisplay.setText(
                      "Scroll position will appear here.");
        }//end onError
      }//end constructor
    );//end addLoadListener

    //Instantiate and register a ScrollListener object to
    // report on the scrolling status, in terms of the
    // distances of the sliders from the top and the left
    // side.
    scrollPanel.addScrollListener(
      new ScrollListener(){
        public void onScroll(
               Widget sender,int scrollLeft,int scrollTop){
          scrollDisplay.setText("Scroll: Left = " 
                    + scrollLeft + ", Top = " + scrollTop);
        }//end onScroll
      }//end constructor
    );//end addScrollListener

    //Add the DockPanel to the browser window.
    RootPanel.get().add(dockPanel);
    
  }//end onModuleLoad method
}//end class


Listing 31. Host page for GwtApp014.

<!---------------------------------------------------------
File GwtApp014.html
GWT host page.
Revised: 11/19/06
---------------------------------------------------------->
<html>
<head>
<title>Wrapper HTML for GwtApp014</title>
<meta name='gwt:module' content='GwtApp.GwtApp014'>

</head>

<body>
<script language="javascript" src="gwt.js"></script>
<iframe id="__gwt_historyFrame" 
              style="width:0;height:0;border:0"></iframe>

<h3>GwtApp014</h3>

<p>Demonstrates WindowResizeListener</p>


</body>
</html>


Listing 32. Java code for GwtApp014.

/*File GwtApp014.java
Copyright 2006, R.G.Baldwin

The purpose of this application is to demonstrate the use
of the WindowResizeListener interface to monitor and
display the size of the browser window.

Uses a static method of the Window class to register a
listener object of type WindowResizeListener on the
browser window. Uses static methods of the Window class to
get the initial size of the browser window.  Places a
Label object in the browser window that displays the
initial size.

Defines a class that implements the WindowResizeListener
as an inner class to make it easy for the event handler
method to access the label.  Registers an object of this
class on the browser window as described above.

When the user resizes the browser, the event handler
displays the new width and height of the browser window
in the label.

Tested using J2SE 5.0, GWT version 1.2.22, and 
jakarta-tomcat-5.0.27 running as a localhost server
under WinXP.
**********************************************************/

package GwtApp.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.user.client.*;

public class GwtApp014 implements EntryPoint{

  Label label = new Label("");//Display window size here.

  //This is the entry point method.
  public void onModuleLoad(){
    //Instantiate an anonymous listener object from an
    // inner listener class and register it on the window.
    Window.addWindowResizeListener(new WinResizeLstnr());
    
    //Display the initial size of the browser window in
    // the label.
    label.setText("Initial size is " 
                               + Window.getClientWidth() 
                               + " x " 
                               + Window.getClientHeight());

    //Add the label to the browser window.
    RootPanel.get().add(label);
  }//end onModuleLoad method
  //=====================================================//

  //This is a listener class.  Make it an inner class so
  // that it will have direct access to the label in order
  // to display the new width and height of the browser
  // window.
  class WinResizeLstnr implements WindowResizeListener{
    public void onWindowResized(int width,int height){
      label.setText(
                   "Resized to " + width + " x " + height);
    }//end onWindowResized
  }//end class WinResizeLstnr

}//end class GwtApp014


Listing 33. Host page for GwtApp015.

<!---------------------------------------------------------
File GwtApp015.html
GWT host page.
Revised: 11/19/06
---------------------------------------------------------->
<html>
<head>
<title>Wrapper HTML for GwtApp015</title>
<meta name='gwt:module' content='GwtApp.GwtApp015'>

</head>

<body>
<script language="javascript" src="gwt.js"></script>
<iframe id="__gwt_historyFrame" 
              style="width:0;height:0;border:0"></iframe>

<h3>GwtApp015</h3>

<p>Demonstrates WindowCloseListener</p>


</body>
</html>


Listing 34. Java code for GwtApp015.

/*File GwtApp015.java
Copyright 2006, R.G.Baldwin

The purpose of this application is to demonstrate the use
of the WindowCloseListener interface to display a 
confirmation dialog when the user attempts to close the
browser window or to navigate to a different site.

Uses a static method of the Window class to register a
listener object of type WindowCloseListener on the
browser window.

Defines a class that implements the WindowCloseListener
as an inner class.  Registers an object of this
class on the browser window as described above.

When the user attempts to close the browser or navigate 
to a different site, the event handler returns a string 
that is embedded into a confirmation dialog that asks the 
user whether or not she wishes to navigate away from the 
page.

Tested using J2SE 5.0, GWT version 1.2.22, and 
jakarta-tomcat-5.0.27 running as a localhost server
under WinXP.
**********************************************************/

package GwtApp.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.user.client.*;

public class GwtApp015 implements EntryPoint{

  //This is the entry point method.
  public void onModuleLoad(){
    //Instantiate an anonymous listener object from an
    // inner listener class and register it on the window.
    Window.addWindowCloseListener(new WinCloseLstnr());
  }//end onModuleLoad method
  //=====================================================//

  //This is a listener class that is defined as an inner
  // class.
  class WinCloseLstnr implements WindowCloseListener{
    
    public java.lang.String onWindowClosing(){
      return "Msg from your WindowCloseListener";
    }//end onWindowClosing
    
    //The following method is empty, and therefore is of
    // no consequence in the behavior of the application.
    public void onWindowClosed(){
      //Fired after the browser window closes or navigates
      // to a different site. This event cannot be
      // cancelled, and is used mainly to clean up
      // application state and/or save state to the server.
    }//end onWindowClosed
      
  }//end class WinCloseLstnr

}//end class GwtApp015

Copyright

Copyright 2007, Richard G. Baldwin.  Reproduction in whole or in part in any
form or medium without express written permission from Richard Baldwin is
prohibited.

Download

Resources

About the author

Richard Baldwin is a
college professor (at Austin Community College in Austin, TX) and private
consultant whose primary focus is a combination of Java, C#, and XML. In
addition to the many platform and/or language independent benefits of Java and
C# applications, he believes that a combination of Java, C#, and XML will become
the primary driving force in the delivery of structured information on the Web.

Richard has participated in numerous consulting projects and he
frequently provides onsite training at the high-tech companies located in and
around Austin, Texas.  He is the author of Baldwin’s Programming
Tutorials, which have gained a
worldwide following among experienced and aspiring programmers. He has also
published articles in JavaPro magazine.

In addition to his programming expertise, Richard has many years of
practical experience in Digital Signal Processing (DSP).  His first job after he
earned his Bachelor’s degree was doing DSP in the Seismic Research Department of
Texas Instruments.  (TI is still a world leader in DSP.)  In the following
years, he applied his programming and DSP expertise to other interesting areas
including sonar and underwater acoustics.

Richard holds an MSEE degree from Southern Methodist University and has
many years of experience in the application of computer technology to real-world
problems.

Baldwin@DickBaldwin.com

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories