JavaEnterprise JavaControlling layout in AJAX web applications using the GWT and Java

Controlling layout in AJAX web applications using the GWT and Java

Java Programming Notes # 2552


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.

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)
.

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

  • Create an HTML host page for the application.
  • Create your own CSS style sheets.
  • Compile your Java code using a special GWT Java-to-JavaScript compiler.
  • Use a special scaled down version of the Java API, which only

    supports two packages from the standard J2SE API:

    • java.lang
    • java.util

Packages not fully supported

Even those two Java packages are not fully supported by the GWT.  For example, although the Vector class is supported by the GWT, only two overloaded constructors for that
class are supported, whereas the Vector class in Sun’s J2SE has four overloaded
constructors.

Not the latest version of Java

In addition, GWT version 1.1.10 is apparently based on version 1.4.2 of
Sun’s J2SE.  Therefore, many of the features that were added in J2SE 5.0
(such as generics)
are not supported by the GWT.

You need to be careful

Therefore, you need to be careful when writing your Java application to make
certain that you are using only those Java features that are supported by the
GWT.  (See the link to the GWT JRE Emulation Library in
Resources for more information on this
topic.)

Second in a series

This is the second lesson in a series designed to help you learn
how to use the GWT to create rich Ajax web applications.

Purpose of the tutorial

The main purpose of the tutorial is to help you learn how to
control the layout of a GWT Ajax web application using HTML layout capabilities,
the capabilities of the layout classes in the GWT API, and a combination of the
two.

A secondary purpose is to teach you some essential aspects
of the creation, testing, and deployment of GWT Ajax web applications that I was
unable to include in the first lesson.

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. Screen shot of a simple web
    application at startup.
  • Figure 2. Screen shot of the simple web
    application after clicking the button.
  • Figure 3. GWT Development Shell.
  • Figure 4. Wrapper HTML for GwtApp003.
  • Figure 5. Compilation error message.
  • Figure 6. Development shell showing results of a compiler error.
  • Figure 7. Screen output for ScrollPanel using CSS styling.
  • Figure 8. Screen output for ScrollPanel without
    fixing the height.
  • Figure 9. List of available layout classes.
  • Figure 10. User interface for an application that uses an HTML table for
    layout.
  • Figure 11. Intended behavior of the DockPanel class.
  • Figure 12. Actual behavior of the DockPanel class.
  • Figure 13. Screen shot of user interface using the DockPanel class.
  • Figure 14. User interface for GwtApp008 at startup.
  • Figure 15. User interface after navigating to a different web site using
    hyperlinks in west cell.
  • Figure 16. User interface after adjusting scroll bars on image.
  • Figure 17. Combined HTML and GUI class layout.

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 at

www.DickBaldwin.com
.


Essential background information

Most of what you need to know to get started using the GWT to create Ajax web
applications was explained in the earlier lesson entitled "Creating Ajax web
applications using the Google Web Toolkit (GWT) and Java, Getting Started"
(see Resources)
However, there are a few essential items that I was unable to include in that
lesson.  Before getting into the details of the main topic of this lesson
(controlling layout in web apps), I will explain those
remaining essential items.  I will illustrate them using the simplest GWT Ajax
web application that I was able to write.

A host page is required

Every GWT web application requires an HTML host page, which can be simple or
complex, whichever you prefer.  However, there are a few essential items that
must be contained in the host page regardless of its simplicity.  A simple
GWT host page is shown in Listing 1.


Listing 1. A simple GWT Ajax host page.


<!--File GwtApp003.html
   Simple GWT host page.
   Revised: 10/17/06-->

<html>
<head>
<!-- Use normal html in the header.                   -->
<!-- Any title is fine                                -->
<title>Wrapper HTML for GwtApp003</title>

<!-- The module reference below is the link           -->
<!-- between html and your Web Toolkit module         -->
<meta name='gwt:module' content='GwtApp.GwtApp003'>
</head>
<body>
<!-- This script is required bootstrap stuff.         -->
<!-- You can put it in the HEAD, but startup          -->
<!-- is slightly faster if you include it here.       -->
<script language="javascript" src="gwt.js"></script>

<!--OPTIONAL: include this if you want history support-->
<iframe id="__gwt_historyFrame" 
              style="width:0;height:0;border:0"></iframe>

<h3>GwtApp003</h3>
<p>This is quite possibly the simplest possible 
event-driven GWT Ajax web app that can be written. This
HTML text and the h3 element shown above can be 
eliminated, leaving only a paragraph element with an 
element identifier that can be referenced by the Java 
code.</p>

<p id="component"></p>

</body>
</html>

What are the essential items?

If you are familiar with the creation of HTML web pages, you already know that
there are a number of items that are essential to all HTML web pages.  I
won’t address those items in this discussion.  Rather, I will limit my
discussion to those items that are essential to the host page for a GWT web
application.  Those items are highlighted in boldface in Listing
1.

The meta name element

The first boldface item in Listing 1 is an element that begins with the word
meta.  To be perfectly honest, there are some things about the GWT
that I am unable to explain beyond the somewhat cryptic explanations that I
have found in the GWT literature.  This is one of those things.  Just
remember to always include this item in your host page.

The script element

If you refer to the lesson that I published several years ago entitled
"JavaScript Programming for Beginners – Introduction" (see
Resources)
, you will find a section entitled
Specifying a File Containing JavaScript Code
.  That section explains the syntax for
a script element that does just what the title suggests.  I will let that explanation
suffice for the explanation of the script element in Listing 1.

History support

One of the controversies that has been brewing in the area of Ajax
applications is the extent to which Ajax does or does not provide history support
coupled with the behavior of the browser’s
back
button.  Google claims to have resolved that issue through
inclusion of the iframe element shown in Listing 1. 
This is another of those items that I can’t explain, so I am forced to simply take Google’s
word for it and include the element in the host page.  As I understand from
the GWT literature,
you must match this element exactly in order for it to do its job correctly.

The id attribute

An empty host page
It is also possible to leave the body of the host page empty if you want to create a completely dynamic
user interface.  If you leave the body of the host page empty, you will
need to use a statement similar to the following to connect the Java code to
the host page: RootPanel.get().add(...) I will show you an example of this later in this lesson.

In order for this process to work as advertised, there has to be a way to connect the Java code to the host page. 
The most obvious way to create that connection is through the
use of one or more elements containing id attributes having unique
values in the host page.  (If you would like to learn more about id attributes, see the
document entitled "The global structure of an HTML document" in
Resources.)
  The Java code can then refer to
the elements identified by the id attributes.

Listing 1 contains a paragraph element with an id attribute having
the value component.  That is sufficient to connect the Java code
shown in Listing 2 to the host page for this simple web application.

Make it a little simpler
Actually, I could have made it a little simpler by avoiding the use
of the paragraph element with the unique id-attribute value of component in
the host page of Listing 1.

(Having made this statement, I expect that
I will receive numerous email messages with even simpler event-driven GWT
Ajax web applications.)

The Java source code

The Java source code for this web application is shown in Listing 2.  The main purpose of this class is to illustrate the essential
ingredients of a very simple GWT Ajax web application.

This class, in conjunction with the corresponding HTML host page named
GwtApp003.html (shown in Listing 1) may constitute the
simplest event-driven GWT Ajax web application that it is possible to write.


Listing 2. The Java source code.


/*File GwtApp003.java
Copyright 2007, R.G.Baldwin
**********************************************************/

package GwtApp.client;

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

public class GwtApp003  implements EntryPoint{

  //This is the entry point method.
  public void onModuleLoad(){
    final Button button = new Button("Click me.");

    button.addClickListener(
      new ClickListener(){
        public void onClick(Widget sender){
          button.setText("Ouch");
        }//end onClick method
      }//end constructor
    );//end addClickListener method
    
    RootPanel.get("component").add(button);
  }//end onModuleLoad method
}//end class

Behavior of the Java code

The host page contains a single paragraph element with an element identifier
named component that can be referred to by the entry point method of this
class.  The entry point method named onModuleLoad
performs the following actions:

  • Instantiates a single button object.
  • Registers a simple anonymous listener object of type
    ClickListener on the button object to
    change the text on the face of the button when the button is clicked.
  • Adds the button to the web page.

Aspects peculiar to GWT

There are many aspects to this source code that are peculiar to, and required
by the GWT.  They are highlighted in boldface in Listing 2.

The package

Recall from the previous lesson entitled "Creating Ajax web
applications…" that the starting
point for creating a GWT web application named GwtApp003 is to execute the following command at
the command-line prompt:

C:...applicationCreator GwtApp.client.GwtApp003

Explanation
The ellipses in the above command specify the path to the script named

applicationCreator.cmd in your installation of the GWT framework.

You can specify the package using any directory
names that you choose, but the package should terminate with the name of a
directory named client for GWT compatibility.  Here is what the GWT
documentation has to say about this topic: "Based on the
recommended GWT project structure, your main GWT application class
should be in a subpackage client."

The
boldface material in the above command specifies the package into which you want to
place the application.

This package is reflected in the package directive in the Java source code in Listing 2.

Import directives

As I understand it, the first import directive shown in Listing 2 is required for all GWT web
applications.  The second import directive is required if the web
application will include any graphical user interface components.

The wild-card character
As is always the case with Java, the second import directive can be
replaced by one or more import directives that use actual class names in place of the wild-card character. 
That is
probably a better approach.  At least it is an approach that is more
expressive of the requirements.

The class with the entry point method named
onModuleLoad

The application can contain many Java class definitions.  At least one of the class
definitions must contain the entry point method named onModuleLoad
That class must implement the interface named EntryPoint.

The onModuleLoad method

Although there are some significant differences, writing a GWT web
application is similar to writing an event-driven Java desktop application. 
For those who are accustomed to writing such desktop applications, the method
named onModuleLoad effectively replaces the purpose of the main
method in a Java desktop application.  Execution begins and ends in this
method.

Here is what the online GWT documentation has to say about this method:

"The entry point method, called automatically by loading a module that
declares an implementing class as an entry-point."

What is a module?

Here is part of what the online GWT documentation has to say about modules:

Individual units of GWT configuration are XML files called modules. A
module bundles together all the configuration settings that your GWT project
needs, namely

  • Inherited modules
  • An entry point application class name; these are optional, although
    any module referred to in HTML must have at least one entry-point class
    specified
  • Source path entries
  • Public path entries
  • Deferred binding rules, including property providers and class
    generators

Modules may appear in any package in your classpath, although it is
strongly recommended that they appear in the root package of a standard project
layout.

I won’t attempt to elaborate on or to explain the above description (not that I
could if I wanted to)
.

An event handler

To add some interest to this web application, I placed a
button in the browser’s client area (see Figure 1).  I registered a ClickListener
object
on the button to cause it to change the text on the face of the button from
"Click me" to "Ouch" when the user clicks the button.

The instantiation of the Button object and the
registration of the listener on the button use the same syntax as standard
Java.  However, standard Java does not have a ClickListener
interface. This listener interface is very similar to the
ActionListener interface in standard Java.  As with
the ActionListener interface, the
ClickListener interface declares a single
method.  However, that method is named onClick
instead of actionPerformed as is the case in standard Java.

Add the button to the user interface

The final boldface item in Listing 2 refers to the element id
with a unique value of component (see Listing 1) and adds the button to the user interface
between the beginning and ending tags of the paragraph element shown in Listing
1.

Here is what the GWT online documentation has to say about the
RootPanel class:

"The panel to which all other widgets must ultimately be added. RootPanels
are never created directly. Rather, they are accessed via
RootPanel.get.

Most applications will add widgets to the default root panel in their
EntryPoint.onModuleLoad methods."

The RootPanel.get method

The GWT documentation has this to say about the RootPanel.get() method:

"Gets the default root panel. This panel wraps the body of the browser’s
document. This root panel can contain any number of widgets, which will be laid
out in their natural HTML ordering. Many applications, however, will add a
single panel to the RootPanel to provide more structure."

The RootPanel class provides two overloaded versions of the
get method. The version described above has an empty argument
list.  (I will show you an example of the use of this version later in
this lesson.)
  The version used in Listing 2 does not have an empty
argument list.  The GWT documentation has this to
say about the version of the method that is called in Listing 2:

"Gets the root panel associated with a given browser element. For this to
work, the HTML document into which the application is loaded must have specified
an element with the given id."

Root panel is created automatically

Note that the root panel is created automatically.  There is nothing in
the host page in Listing 1 or the Java code in Listing 2 that explicitly
instantiates an object of the RootPanel class.

Note also that this application does not add another panel to the root panel
as suggested in the above quotation. 
However, some of the applications discussed later in this lesson will do that.

Application testing

This application was tested in hosted mode during development. 
(See the earlier lesson entitled "Creating Ajax web applications…" for an explanation of hosted mode.)

This application was developed using J2SE 5.0 and GWT version 1.1.10. 
Following development, it was tested by compiling it using the script named
GwtApp003-compile.cmd
and deploying it in a jakarta-tomcat-5.0.27 server running
as a localhost server under WinXP.

Runtime screen shot at startup

Figure 1 shows a screen shot of the application running in a Firefox browser
at startup.


Figure 1. Screen shot of a simple web application at
startup.


Runtime screen shot after clicking the button

Figure 2 shows a screen shot of the web application after the button has
been clicked.  Note that the text on the face of the button in Figure 2 reads
"Ouch" instead of "Click me."


Figure 2. Screen shot of the simple web application after
clicking the button.


Exhibits Ajax-like behavior

Also note the highlighted text in Figure 2.  This text was highlighted
before the button was clicked.  It remained highlighted after the button
was clicked and the text on the face of the button changed.  This
demonstrates the Ajax-like behavior of the application.  In particular, the
display was updated to show the new text on the face of the button without a
requirement to download and display a complete new copy of the web page in the
browser.  Only that portion of the web page that changed was updated. 
As I understand it, this is Ajax-like behavior.

Web application development in hosted mode

The earlier lesson entitled "Creating Ajax web applications…" explained how you can execute the script named
GwtApp003-shell.cmd to compile and execute the web
application in hosted mode.  When you do that, two separate GWT
browsers appear on the screen.

The first browser to appear,
(Entitled GWT Development Shell and referred to hereafter simply as the
shell)
, is
shown in Figure 3.  (Figure 3 is representative of what you will see
when the operation is successful.)


Figure 3. GWT Development Shell.


Not very exciting

As you can see, when the operation is successful, the shell doesn’t provide
much in the way of information.

The second GWT browser

The second of the special GWT browsers to appear, (entitled Wrapper HTML for GwtApp003
and referred to hereafter simply as the wrapper)
, is shown in Figure 4.  (Figure 4 is representative of what you will see
when the operation is successful.  The title in the title bar in Figure 4 comes from the title element in the host page.)


Figure 4. Wrapper HTML for GwtApp003.


When the operation is successful, the wrapper displays the initial state of
the web application as currently defined by the host page and the Java code.

An effective development process

This application development process based on the use of hosted mode works
quite well.  Once the application appears in the browser, you can exercise
it just as though it is running on a real server and you have executed it using
a real browser.

Compiling the application
Note that when I speak of compiling the application in hosted mode,
that is not the same as compiling it into a JavaScript application intended
for deployment.

If you make changes to either the Java source code or to the host page and
then click the Refresh button in Figure 4, the application will be
recompiled and re-executed taking the changes into account, and the results will appear in the shell and the
wrapper.  This leads to a smooth development process.

When things don’t go as planned in hosted mode

Sometimes things don’t go as planned (perish the thought) and the
process of compiling and executing the web application in hosted mode doesn’t end successfully. 
Your first clue that something is wrong will be when you see an error
message similar to that shown in Figure 5.


Figure 5. Compilation error message.


As you can see, the error message will direct you to the shell for more
information.

A compiler error

Figure 6 shows the result of forcing a compiler error in an attempt to
compile and execute the application named GwtApp003 in hosted mode.


Figure 6. Development shell showing results of a compiler error.


A forced compiler error
I forced the compiler error shown in Figure 6 by turning the first
import directive in Listing 2 into a comment, thereby making it impossible
for the compiler to locate and load a required class file.

As in most programming scenarios, you will need to find and fix the problem
before you can successfully compile and execute the web application.

CSS styling

The GWT does not provide its own styling capability.  Rather, it depends
on the use of Cascading Style Sheets (CSS) (see the Cascading Style Sheets
Home Page in
Resources
)
to control the style of components in the user interface.

There are at least two ways to include CSS styling material in a GWT web application:

  • Embed the styling material directly in the host page.
  • Use a separate stylesheet file.

I will show you examples of both approaches in this section.

I will also show you how to use a host page with an essentially empty body
and make the connection between the host page and the Java code.

Finally, I will illustrate the use of the HTML class from
the GWT API.

CSS styling is not always optional

Contrary to what the GWT documentation would lead you to believe, apparently the use of
CSS styling is not always optional.  I will illustrate the use of CSS
styling using an object of the GWT ScrollPanel class.  While I
don’t plan to discuss many of the characteristics of the ScrollPanel
class in this section, I chose to use it for a very specific reason.

As near as I can determine, an object of the ScrollPanel class
doesn’t know how to act like a scroll panel unless you fix its height.  If
you don’t fix the height, the height of the panel simply expands as necessary to
accommodate its contents.  No scroll bars appear.

The only way that I know of to fix the height of a scroll panel is through
the use of CSS styling.  Therefore, unless I am missing something, the use
of CSS styling is not optional if you want to use a ScrollPanel
object and have it behave the way that a scroll panel should behave.

The screen output for GwtApp006

Figure 7 shows the screen output for the user interface for the application
named GwtApp006 with the styling properly used to fix the height of the scroll
panel at 256 pixels.  As you can see, the panel contains scroll bars.


Figure 7. Screen output for ScrollPanel using CSS styling.


The screen output with no scroll bars

Figure 8 shows the screen output for the scroll panel with the CSS
specification for the height removed.  The content of the scroll panel was
exactly the same in Figure 7 and Figure 8.


Figure 8. Screen output for ScrollPanel without fixing
the height.


Didn’t behave like a scroll panel should behave

Didn’t remove all styling
I purposely didn’t remove all of the styling for the scroll bar in
Figure 8.  Rather, I only removed the height specification.  I
allowed the specifications for the border, the padding, and the text color
to remain as it was to show that the problem was strictly the result of failing to
specify the height.  Had I removed all of the styling, the result would
simply have been black HTML text on a white background.

As you can see, the scroll panel in Figure 8 didn’t behave like a scroll
panel should behave.  Rather, it simply expanded its height to accommodate
the content and did not produce scroll bars.  The vertical scroll bar that
you see in Figure 8 belongs to the browser window and not to the scroll panel.

The Java source code

The purpose of this class is to illustrate the following GWT programming
concepts:

  • Embedded style element in the host page.
  • Empty body in the host page.
  • Use of a scroll panel (without much explanation)

The body of the host page is empty. Therefore, this Java code is compatible with an
empty body in a host page.

As usual, this application was tested in hosted mode during development, and
was also deployed and tested using J2SE 5.0, GWT version 1.1.10, and
jakarta-tomcat-5.0.27 running as a localhost server under WinXP.

The Java source code for this application is shown in Listing 3.


Listing 3. Java source code for GwtApp006.


/*File GwtApp006.java
Copyright 2007, R.G.Baldwin
**********************************************************/

package GwtApp.client;

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

public class GwtApp006 implements EntryPoint{

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

    //Instantiate an HTML object that will serve as the
    // content for a ScrollPanel object.
    HTML content = new HTML(
      "<h3>GwtApp006</h3>"
      + "<p>The purpose of this class is to illustrate "
      + "the following GWT programming concepts:</p>"
      + "<ol>"
      + "<li>Embedded style element in the host page.</li>"
      + "<li>Empty body in the host page.</li>"
      + "<li>Use of a scroll panel (without elaboration)"
      + "</li>"
      + "<li>Use of an HTML object</li>"
      + "</ol>"
      + "<p>The body of the host page is empty. This Java "
      + "code is compatible with an empty body in a host "
      + "page.</p>"
      + "<p>Tested using J2SE 5.0, GWT version 1.1.10, "
      + "and jakarta-tomcat-5.0.27 running as a localhost "
      + "server under WinXP. </p>");
      
    //Instantiate a new ScrollPanel object.
    ScrollPanel scrollPanel = new ScrollPanel(content);
    
    //Establish a name by which the CSS style material can
    // refer to the ScrollPanel object.
    scrollPanel.setStyleName("scrollPanel");

    //Use this syntax for a host page with an empty body.
    RootPanel.get().add(scrollPanel);
    
  }//end onModuleLoad method
}//end class

The HTML object

The code in Listing 3 begins by instantiating a new object of the
HTML class and populating the object with the HTML
text that will be used as content for the scroll panel. Although
this is something of a pain to do from a typing viewpoint, the
concepts involved in instantiating and populating the object are
straightforward.

The ScrollPanel object

Next, the code in Listing 3 instantiates and populates the scroll panel. 
Again, the concepts involved are straightforward.

The name of the style for the scroll panel

Next, the code invokes the setStyleName method
on the scroll pane object to establish a handle by which the
CSS styling material can reference the scroll pane (see Listing 4).

Place the scroll pane in the browser window

Finally, the code invokes the get() method on
the RootPanel to place the scroll pane in the
browser window.  Note that unlike the previous examples, no parameter is
passed to the get method.  This is the syntax that is used to place the panel
in the browser window without a requirement to reference an element identifier. 
This makes it possible to use a host page for which the HTML body is essentially
empty of content.

The host page

The host page is shown in Listing 4.


Listing 4. Host page for GwtApp006.


<!---------------------------------------------------------
File GwtApp006.html
GWT host page.
Revised: 10/19/06
---------------------------------------------------------->
<html>
<head>
<title>Wrapper HTML for GwtApp006</title>

<!--This is the embedded style element that is being
    illustrated by this application. Note that it is
    positioned in the head element.-->
<style>
  .scrollPanel{
    height: 256px;
    border: 4px solid #FF0000;
    padding: 8px;
    color: DARKBLUE
  }
</style>

<meta name='gwt:module' content='GwtApp.GwtApp006'>

</head>

<body>
<!--This body is empty except for the required script
    element and the optional iframe element.-->
<script language="javascript" src="gwt.js"></script>
<iframe id="__gwt_historyFrame" 
              style="width:0;height:0;border:0"></iframe>
</body>
</html>

The CSS styling material

The boldface code in Listing 4 shows the CSS styling material that is
applied to the scroll panel.  For this application, the styling material
was embedded in a style element within the head element of the
host page.  (The next sample application will put the CSS styling
material in a separate stylesheet file.)

I’m not going to try to teach you how to create CSS styling material in
this lesson.  That is a topic for another lesson on another day. 
(I suspect that many of you with web development experience already know more
about CSS stylesheets than I do anyway.)
  There is plenty of good material available on the web. 
For example, several good
resources are available by way of the link to the Cascading Style Sheets Home
Page
in Resources.

However, I do want to point out the use of the scrollPanel handle in
Listing 4 to connect the styling material to the scroll panel. I also want to
point out the height specification of 256 pixels.  (You can probably
figure out what the other items are as well by virtue their names.)

What about that period in the styling material

You may have noticed that there is a period in front of scrollPanel in
the styling material in Listing 4 and you might like to see an explanation as
to why it is there.  You may also have noticed that the Java source code
that established the style name for the scroll panel did not include a period in
the style name.

About all that I can tell you at this point is that while I was trying to
understand how to use CSS material to provide visual styling for GWT components,
I found something in the GWT documentation stating that the period is required. 
(As I recall, the explanation given there wasn’t very enlightening but I’m
unable to reproduce it from memory.)
However, as of this writing, I am
unable to locate that information in the GWT documentation, so I will just
have to tell you that the period is required.

That’s about all that I have to tell you about embedding CSS styling material
in the host page.  Next, I will show you how to use a separate stylesheet
file to accomplish the same thing.

Use of a separate stylesheet file, GwtApp007

Modifying the application to use a separate stylesheet file is easy. 
All that you need to do is:

  • Put the CSS styling material in a separate file.
  • Put the CSS file in the public directory belonging to the application on
    the server.
  • Replace the embedded styling material in the host page with a link to
    the CSS file.

I could leave it at that, but I won’t.  I hate it when I am reading a
tutorial that tells me that something is easy, but then neglects to show
me how to do it.  (Often in those cases, the author will forget to
include a critical step in the "easy" written instructions.)

The Java source code and the screen output

The Java source code for this application is an exact copy of the source code
for the earlier application named GwtApp006 shown in Listing 3, which uses
embedded CSS styling material. No change is required in the Java code to
upgrade to the use of a stylesheet file. (The Java code doesn’t know, and
doesn’t care about CSS styling.)
  All of the changes involve:

  • The creation
    of the separate stylesheet file.
  • Modifications to the host page to cause it to reference that file.

Therefore, there would be no point in me showing
you another view of the Java source code.

The screen output

In addition, the screen output for this application is exactly the same as
for the earlier application named GwtApp006 shown in Figure 7.  Therefore,
there would also be no point in me showing another screen shot representing the
screen output from GwtApp007.

The stylesheet file

However, this application contains a new file that wasn’t a part of any of
the earlier applications: the stylesheet file named GwtApp007.css.  (I
believe that you could probably name the file anything you choose as long as you are
consistent in the use of the name, but I’m not certain about that.)

The contents of the stylesheet file are shown in Listing 5.


Listing 5. The stylesheet file for GwtApp007.


  .scrollPanel{
    height: 256px;
    border: 4px solid #FF0000;
    padding: 8px;
    color: DARKBLUE
  }

You will recognize that the contents of the stylesheet file match the contents of the script element
in Listing 4.

The host page

Listing 6 is a listing of the revised host page.  The new material in
Listing 6 (relative to Listing 4) is highlighted in boldface.


Listing 6. The host page.


<!---------------------------------------------------------
File GwtApp007.html
GWT host page.
Revised: 10/19/06
---------------------------------------------------------->
<html>
<head>
<title>Wrapper HTML for GwtApp007</title>

<!--This is the link to the separate stylesheet file that 
    is being illustrated by this application. Note that it 
    is positioned in the head element.-->
<link rel="stylesheet" href="GwtApp007.css">

<meta name='gwt:module' content='GwtApp.GwtApp007'>
</head>

<body>
<!--This body is empty except for the required script
    element and the optional iframe element.-->
<script language="javascript" src="gwt.js"></script>
<iframe id="__gwt_historyFrame" 
              style="width:0;height:0;border:0"></iframe>
</body>
</html>

The only change…

The only change in the revised host page relative to that used for GwtApp006
is the replacement of the entire script element in Listing 4 by a link to the
stylesheet file in Listing 6.  You will probably recognize the file name of the
stylesheet file in the boldface text.  If you want to know more about the
remainder of the link element, you can look it up in a good HTML/CSS
tutorial.

And that pretty well wraps up my discussion of the use of CSS styling with
the GWT.

Discussion
and sample code


Now that we have covered the essential background information, it’s time to move on
to the main purpose of this lesson; teaching you how
to control the layout of the user interface in GWT Ajax web applications.

Layout at the HTML level

Controlling the layout of a GWT web application is an interesting task because you
are faced with an almost unlimited number of possibilities.  To begin with,
if you are skilled in the construction of HTML web pages, you can provide one
level of layout control by using element identifiers to specify the locations of
the various GUI components in the HTML page.

Layout at the GUI class level

In addition, you can add another level of control over the layout through the
use of one or more of the classes listed in Figure 9.


Figure 9. List of available layout classes.


Available Layout Classes

  • AbsolutePanel – An absolute panel positions all of its children
    absolutely, allowing them to overlap.
  • CellPanel – A panel whose child widgets are contained within the cells
    of a table. Each cell’s size may be set independently. Each child widget can
    take up a subset of its cell and can be aligned within it.
  • DeckPanel – A panel that displays all of its child widgets in a ‘deck’,
    where only one can be visible at a time. It is used by TabPanel.
  • DockPanel – A panel that lays its child widgets out "docked" at its
    outer edges, and allows its last widget to take up the remaining space in
    its center.
  • FlowPanel – A panel that formats its child widgets using the default
    HTML layout behavior.
  • FocusPanel – A simple panel that makes its contents focusable, and adds
    the ability to catch mouse and keyboard events.
  • FormPanel – A panel that wraps its contents in an HTML <FORM> element.
    This panel can be used to achieve interoperability with servers that accept
    traditional HTML form encoding. The following widgets will be submitted to
    the server if they are contained within this panel:

    • TextBox
    • PasswordTextBox
    • RadioButton
    • CheckBox
    • TextArea
    • ListBox
    • FileUpload
  • HorizontalPanel – A panel that lays all of its widgets out in a single
    horizontal column.

  • HTMLPanel – A panel that contains HTML, and which can attach child
    widgets to identified elements within that HTML.

  • PopupPanel – A panel that can "pop up" over other widgets. It overlays the
    browser’s client area (and any previously-created popups).

  • ScrollPanel – A simple panel that wraps its contents in a scrollable area.

  • StackPanel – A panel that stacks its children vertically, displaying only
    one at a time, with a header for each that the user can click to display it.

  • TabPanel – A panel that represents a tabbed set of pages, each of which
    contains another widget. Its child widgets are shown as the user selects the
    various tabs associated with them. The tabs can contain arbitrary HTML.

  • VerticalPanel – A panel that lays all of its widgets out in a single
    vertical column.

An almost unlimited number of combinations

When you combine the layout possibilities at the HTML level with the layout
possibilities at the GUI class level, the number of possible combinations is
almost unlimited.  Thus, you should never go wanting for GUI layout
options when creating GWT web applications.

Obviously, I won’t be able to show you enough examples in this lesson to make much of a dent
in the total number of possible layouts.  However, I will
show you some examples at both levels, and also at a combination of the two levels. 
Hopefully you will be able to build upon those examples to create your own
favorite layouts.

HTML layout

Because I have no expertise in constructing HTML pages, I’m certain that many
of you will have more ability than I have to design creative layouts at the HTML
level.  However, despite my lack of expertise in the area, I will demonstrate one simple HTML layout possibility for
the benefit of readers who also lack HTML expertise.  This layout
will use a common HTML table to position four GUI components.

Screen shot of the user interface for GwtApp004

Figure 10 shows a screen shot of the user interface with the application
being executed in a Firefox browser.  This screen shot shows the state of
the user interface after the user has clicked the button labeled ButtonB.


Figure 10. User interface for an application that uses an HTML table for layout.


The host page

Listing 7 shows the HTML host page for this application.


Listing 7. Host page for the application named GwtApp004.


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

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

<h3>GwtApp004</h3>
<p>This application illustrates the use of an HTML 
table to control the layout of the user interface. This
HTML text and the h3 element shown above can be 
eliminated, leaving only a table element with four element
identifiers that can be referenced by the Java 
code. The table borders can also be eliminated to hide the 
fact that a table is being used to control the layout.
</p>

<table border="1">
	<tr>
		<td id="componentA"></td>
		<td id="componentB"></td>
	</tr>
	<tr>
		<td id="componentC"></td>
		<td id="componentD"></td>
	</tr>
</table>

</body>
</html>

The new material

Table borders
The table borders were shown in this application to make it obvious
how the table was being used to position the GUI components.  As
indicated in Figure 10, the borders can be eliminated to hide the fact that
a table is being used to control the layout.

The new material in Listing 7 is highlighted in boldface.  If you are
familiar with HTML, you will recognize this material as the HTML code for a
table having two rows and two columns with borders.  Thus, the table has
four cells as shown in Figure 10.

Unique element identifiers

A unique element identifier is specified for each of the table-data (<td>)
elements in the host page.  As you learned earlier in this lesson, these element identifiers
can be used by the Java code to place
a different GUI component in each cell in the table.

Components in the table

Analogous to a TextField object
This would be a TextField object in standard Java. 
It is troubling to me that Google elected to make subtle changes to the
names of some of the standard GUI components relative to standard Java. 
This makes it more of an effort for an experienced Java programmer to write
web applications using the GWT than would be the case if Google had used the
standard Java names for those components.

As shown in Figure 10, the two cells in the
left column each contain a button.  When the user clicks on one of the
buttons, the identification of the clicked button is displayed in the text box
in the bottom cell in the right column.

The top cell in the right column
contains a label.  As mentioned above, the bottom cell in the right column contains a
TextBox object.

The Java code

The purpose of this class is to illustrate the use of an HTML table to
control the layout of the user interface.  No layout classes are used.

The Java source code for this class is shown in Listing 8.


Listing 8. Java source code for the application named GwtApp004.


/*File GwtApp004.java
Copyright 2007, R.G.Baldwin
**********************************************************/

package GwtApp.client;

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

public class GwtApp004 implements EntryPoint{

  //This is the entry point method.
  public void onModuleLoad(){
    final Button buttonA = new Button("Button A");
    final Button buttonB = new Button("Button B");
    final TextBox textBox = new TextBox();
    textBox.setText("TextBox");
    final Label label = new Label("Please Click a Button");
    
    //Add a ClickListener to each button.
    buttonA.addClickListener(
      new ClickListener(){
        public void onClick(Widget sender){
          textBox.setText("Button A clicked");
        }//end onClick method
      }//end constructor
    );//end addClickListener method
    
    buttonB.addClickListener(
      new ClickListener(){
        public void onClick(Widget sender){
          textBox.setText("Button B clicked");
        }//end onClick method
      }//end constructor
    );//end addClickListener method
    
    //Place the components in the HTML table.
    RootPanel.get("componentA").add(buttonA);
    RootPanel.get("componentB").add(label);
    RootPanel.get("componentC").add(buttonB);
    RootPanel.get("componentD").add(textBox);
    
  }//end onModuleLoad method
}//end class

Unique element identifiers

As shown in Listing 7, the host page contains a table having four cells. 
Each cell contains a unique element identifier that can be referenced by the
Java code.  The element identifiers are:

  • componentA
  • componentB
  • componentC
  • componentD

Instantiate and prepare the GUI components

The code in Listing 8 instantiates two Button
objects, a Label object, and a TextBox
object.  A different ClickListener object is registered
on each button. The purpose of the listener is to display the identification of
the clicked button in the text box.

Then the code in Listing 8 uses references to the unique element identifiers
listed above to place one component in each cell in the HTML table.

Testing the application

Development of this application was accomplished using J2SE 5.0 and GWT
version 1.1.10.  As before, the application was tested in hosted mode
during development.

Once the development was complete and the application compiled and ran
successfully in hosted mode, the application was deployed and tested using a jakarta-tomcat-5.0.27
server running
as a localhost server under WinXP as shown in Figure 10.

GUI class layout

Now you know how to use HTML to control the layout of the user interface for
a GWT Ajax web application, at least for a simple layout based on the use of an
HTML table.  It’s time to address the use of the GWT Java layout classes
for layout control.

Many layout classes available

As you saw in Figure 9, there are many different panel classes available
in the API that can be used to control the layout of the user interface. 
(You saw an example of the ScrollPanel
class in Figure 7, for example.)

Many of the panel classes have a large number of properties.  The panels
can be used in combination to produce composite layouts.  As a result,
there are an almost unlimited number of combinations of panels and
panel-properties that can be used.

The DockPanel class

One of the panel classes listed in Figure 9 is named DockPanel.
This class produces a panel that lays out its child widgets "docked" at its
outer edges, and allows its last widget to take up the remaining space in its
center.  I find this panel to very interesting because it is sort of like the standard Java BorderLayout class on steroids. 
(At least it would be if it behaved as advertised.)

The intended behavior of the DockPanel class

Figure 11 shows the intended behavior of the
DockPanel class.  (I captured the image in Figure 11 from
the online GWT documentation for the DockPanel class.)


Figure 11. Intended behavior of the DockPanel class.


One thing that makes this class very interesting (that is not possible
with the standard Java BorderLayout class)
is that it is possible to create multiple cells parallel to each of the borders in addition to the cell in the
center.  When you consider that any one of those cells can itself contain
another panel object instantiated from one of the classes in Figure 9, you can imagine that
it is possible to begin with this layout and to create a very large number of different composite layouts.

Actual behavior of the DockPanel class

Figure 12 shows the actual behavior of the
DockPanel class.  It has problems.


Figure 12. Actual behavior of the DockPanel class.


So, what’s the problem with Figure 12?

Not my own design
The program that produced the image in Figure 12 is not a program of my
own design.  Rather, the image was produced by Google’s GWT KitchenSink
demonstration program after I inserted a call to the method named setBorderWidth into the program to cause the borders on each of the cells to be
exposed.

It seems fitting that the documentation for the
setBorderWidth method includes the following statement: "Sets the
width of the border to be applied to all cells in this panel. This is
particularly useful when debugging layouts, in that it allows you to see
explicitly the cells that contain this panel’s children."

Perhaps the
folks at Google should have taken their own advice and should have applied the
setBorderWidth method to
the DockPanel class.  Then they would have seen that it
appears to have a bug.  I assume that Google is aware of
this apparent bug in the layout and will correct it in some future release.

If you examine Figure 12 very carefully and compare it with Figure 11, you will see that it differs from
Figure 11 in one very significant way.  In particular, the cell containing
the east component extends all the way to the bottom of the panel.  This in
turn causes the
cell containing the south component to be truncated on the right. 
(According to Figure 11, the south cell should extend all the way from the left
border to the right border of the panel just like the north cell.)

The south cell is truncated on the right

As a
result, the component that is contained in the south cell isn’t centered below
the others.  (I expended quite a lot of time and effort trying to
determine why my application named GwtApp005 suffered
from this symmetry problem before I discovered that it is apparently a bug in
the GWT version 1.1.10 DockPanel class.)

The application named GwtApp005

The application named GwtApp005 uses the DockPanel class, along with
the Button class to illustrate how to control layout using the DockPanel
class.  The user interface produced by this application is shown in Figure
13.


Figure 13. Screen shot of user interface using the DockPanel class.


No listener objects
Note that there are no listener objects registered on any of the
buttons in Figure 13.  Thus, clicking the buttons doesn’t cause
anything to happen other than the visual behavior that is built into the
buttons.

You will note that I allowed the cell borders to remain exposed in Figure 13
so that we can all see why the two buttons that are docked against the south
border are not centered horizontally in the panel.

The Java source code

The Java source code for the web application named GwtApp005 is shown in
Listing 9.


Listing 9. Java source code for the application named GwtApp005.


/*File GwtApp005.java
Copyright 2007, R.G.Baldwin

The purpose of this application is to illustrate the 
use of the DockPanel class for controlling the layout of 
the user interface.

Tested using J2SE 5.0, GWT version 1.1.10, 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 GwtApp005 implements EntryPoint{

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

    //Instantiate a DockPanel object.
    final DockPanel dockPanel = new DockPanel();
    
    //Instantiate seven Button objects that will be used to
    // populate the DockPanel object.
    final Button northButtonA = 
                              new Button("North Button A");
    final Button northButtonB = 
                              new Button("North Button B");
    final Button westButton = new Button("West Button");
    final Button eastButton = new Button("East Button");
    final Button southButtonA = 
                              new Button("South Button A");
    final Button southButtonB = 
                              new Button("South Button B");
    final Button centerButton = 
                               new Button("Center Button");

    //The purpose of the following statement is to cause
    // each component to be horizontally centered in its
    // cell.
    //Note that the statement fails to cause all of the
    // components to be centered.  The south component is
    // offset to the left.  However, that seems to also be
    // true for the layout section of the KitchenSink demo
    // that is avaliable on the GWT website. (It isn't as
    // obvious there because the south component is text
    // only.)
    dockPanel.setHorizontalAlignment(
                                   DockPanel.ALIGN_CENTER);
    //Expose the border for each cell.
    dockPanel.setBorderWidth(5);
    
    //Add the buttons to the panel.
    dockPanel.add(northButtonA, DockPanel.NORTH);
    dockPanel.add(northButtonB, DockPanel.NORTH);
    dockPanel.add(eastButton, DockPanel.EAST);
    dockPanel.add(southButtonA, DockPanel.SOUTH);
    dockPanel.add(southButtonB, DockPanel.SOUTH);
    dockPanel.add(westButton, DockPanel.WEST);
    dockPanel.add(centerButton,DockPanel.CENTER);
    
    //Add the panel to the browser window.
    RootPanel.get().add(dockPanel);
    
  }//end onModuleLoad method
}//end class

The code in Listing 9 is reasonably straightforward and
shouldn’t require much in the way of an explanation beyond the embedded
comments.  However, there are several items that I have highlighted in
boldface that deserve some explanation.

The setHorizontalAlignment method

According to the documentation, this method "Sets the default horizontal
alignment to be used for widgets added to this panel. It only applies to widgets
added after this property is set."

As explained earlier, this method seems to succeed in causing each component
to be horizontally centered in its respective cell.  The problem is that
the south cell is truncated on the right as shown in Figure 12, causing the
south components to be offset to the left relative to all of the other components.

The setBorderWidth method

I explained the purpose of this method earlier.  I invoked the method on
the dock panel in this application to expose the borders on the cells and to
illustrate why the components in the south are not properly centered relative to
the other components.

Multiple components docked to a border

You will note that I added two buttons to the north and two buttons to the
south in Listing 9.  If you compare that code with the image shown in
Figure 13, you will see that the first component added docks against the outer
border of the panel, the next component added docks against that component, etc.

The HTML host page

The HTML code for the host page is shown in Listing 10.  By now, you
should understand everything in Listing 10.


Listing 10. Host page for the application named GwtApp005.


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

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

<h3>GwtApp005</h3>
<p>The purpose of this application is to illustrate the 
use of the <code>DockPanel</code> class for controlling 
the layout of the user interface.</p>

</body>
</html>

A composite user interface, GwtApp008

The next sample application that I will show you illustrates the construction
of a composite user interface based on several different component types. 
A screen shot of the output at startup is shown in Figure 14.


Figure 14. User interface for GwtApp008 at startup.


An assumption
Note that it was assumed that the image would be loaded successfully,
so none of the code normally required to deal with image loading problems
was included.  Dealing with loading problems
would make a good topic for another tutorial on another day.  The image file was
placed in the public directory along with the host page.  You should be
able to replicate these results using just about any image file that you
have available.  Note that Figure 14 shows the application running in
the special GWT browser in hosted mode.

A populated DockPanel object

The main panel is a DockPanel object in which the north, west, and center cells are
populated.  The north cell is populated with an
HTMLPanel containing explanatory
text.  The west cell is populated with an
HTMLPanel containing links to several
other web sites.  The center cell is populated with a
ScrollPanel, which in turn is populated with an
Image object.

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

Following links and returning with the back button

Figure 15 shows the output after the user clicked the bottom hyperlink in the
left panel of Figure 14, and then followed several more hyperlinks in the
resulting web pages.


Figure 15. User interface after navigating to a different
web site using hyperlinks in west cell.


Note that the browser’s back button behaved in the normal way in
retracing the path back from following those hyperlinks.

Adjusting the image scroll bars

Figure 16 shows the screen output after using the browser’s back
button to retrace the path, and then adjusting the scroll bars on the image
relative to Figure 14 in order to view a different portion of the image.


Figure 16. User interface after adjusting scroll bars on image.


The host page

The host page for GwtApp008 is shown in Listing 11.  As you can see,
there is nothing new in this host page relative to what you have already learned
in this lesson except that in this listing, the CSS styling material sets the
width of the scroll pane to 300 pixels.


Listing 11. Host page for GwtApp008.


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

<body>
<!--This body is empty except for the required script
    element and the optional iframe element.-->
<script language="javascript" src="gwt.js"></script>
<iframe id="__gwt_historyFrame" 
              style="width:0;height:0;border:0"></iframe>
</body>
</html>

The Java source code

The Java source code for this application is shown in Listing 12.


Listing 12. Java source code for GwtApp008.


/*File GwtApp008.java
Copyright 2007, R.G.Baldwin

Tested using J2SE 5.0, GWT version 1.1.10, 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 GwtApp008 implements EntryPoint{

  //This is the entry point method.
  public void onModuleLoad(){
    
    //Instantiate a DockPanel object.
    final DockPanel dockPanel = new DockPanel();
    
    //Place an HTMLPanel containing explanatory text in the
    // north cell of the dock panel.
    HTMLPanel htmlPanelNorth = new HTMLPanel(
      "<h3>This sample application illustrates the "
      + "construction of a composite user interface based "
      + "on several different types of components.</h3>");
    dockPanel.add(htmlPanelNorth,DockPanel.NORTH);

    //Instantiate a new HTMLPanel and populate it with a
    // list of hyperlinks to other web sites.  Add it to
    // the west cell of the dock panel.
    String content = 
      "<p><a href="http://www.dickbaldwin.com/toc.htm">"
        + "Table of Contents</a></p>"
      + "<ul>"
      + "<li><a href="http://www.dickbaldwin.com/"
        + "tocint.htm">Intro Java</a></li>"
      + "<li><a href="http://www.dickbaldwin.com/"
        + "tocmed.htm">Intermediate Java</a></li>"
      + "<li><a href="http://www.dickbaldwin.com/"
        + "tocadv.htm">Advanced Java</a></li>"
      + "<li><a href="http://www.dickbaldwin.com/"
        + "tocknowledge.htm">Test Java Knowledge</a></li>"
      + "<li><a href="http://www.dickbaldwin.com/"
        + "tocjscript1.htm">JavaScript</a></li>"
      + "<li><a href="http://www.dickbaldwin.com/"
        + "tocdsp.htm">DSP</a></li>"
      + "</ul>";
    HTMLPanel htmlPanelWest = new HTMLPanel(content);
    dockPanel.add(htmlPanelWest,DockPanel.WEST);
    
    //Place a large image in a small scroll panel and place
    // the scroll panel in the center cell of the dock 
    // panel.
    Image image = new Image("pool.jpg");
    ScrollPanel scrollPanel = new ScrollPanel(image);
    scrollPanel.setStyleName("scrollPanel");
    dockPanel.add(scrollPanel,DockPanel.CENTER);

    //Use this syntax for a host page with an empty body.
    RootPanel.get().add(dockPanel);
    
  }//end onModuleLoad method
}//end class

Not much that is new here

The point of this application is to teach you how to create composite user
interfaces by combining a variety of panels and other interface components. 
Other than that, there was no intention to introduce anything new.  The only thing new in Listing 12 is the use of the
HTMLPanel and Image classes.

The usage of both of those classes in this code was straightforward.  To
reiterate, however, because the image was being loaded from the same directory
as the host page, it was assumed that the image would be loaded successfully. 
Therefore, the code that is normally used to deal with image-loading problems
was omitted for the sake of simplicity.

Combined HTML and GUI class
layout

And last but not least, the next application named GwtApp009 shows you how to
combine the layout capabilities of HTML with the layout capabilities of the GWT
Java API.  The output from this application, which consists of a
combination of slightly modified versions of the earlier applications named
GwtApp006 and GwtApp008, is shown in Figure 17.


Figure 17. Combined HTML and GUI class layout.


Looks a lot like two of the previous applications
combined

If you look carefully, you will note that the upper portion of Figure 17
looks a lot like the screen output shown in Figure 7, and the bottom portion of
Figure 17 looks a lot like Figure 14.  That is not an accident.

I created this application from the two earlier applications by performing the following operations:

  • Created a new host page having two paragraph elements containing unique id attributes.  One element was positioned near the top of
    Figure 17.  The other element was positioned near the bottom of Figure 17.
  • Created an embedded style element in the new host page that would be
    applicable to both scroll pages shown in Figure 17.  (Note, however,
    that I could have chosen to apply different styling to the each scroll page
    if I had assigned different style names to two scroll pages in two of the Java
    class files described below.)
  • Created two new classes named GwtApp009a and GwtApp009b
    by modifying GwtApp006
    and GwtApp008 respectively.  The creation of the two new classes consisted
    mainly of:
    • Causing
      the two classes to extend ScrollPanel and
      DockPanel respectively and not to implement EntryPoint.
    • Converting the methods named onModuleLoad belonging to each of the
      classes into constructors for the new class that performs most of the same operations
      as onModuleLoad.

  • Defined a new class named GwtApp009 (containing a method named
    onModuleLoad)
    that instantiates one object of each of the two new
    classes described above, and places them in the user interface at the
    locations of the two elements having the unique id-attribute values.

Once I got into it, I was surprised at the ease of the conversion.

HTML Host page for GwtApp009

The HTML host page for this application is shown in Listing 13.


Listing 13. Host page for GwtApp009.


<!---------------------------------------------------------
File GwtApp009.html
GWT host page.
Revised: 10/19/06
---------------------------------------------------------->
<html>
<Host page for GwtApp009.9</title>

<style>
  .scrollPanel{
    height: 200px;
    width: 300px;
    border: 1px solid DARKBLUE;
    padding: 4px;
  }
</style>

<meta name='gwt:module' content='GwtApp.GwtApp009'>

</head>

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

</body>
</html>

The embedded style element and the definitions of the two
paragraph elements having unique id attribute values are
highlighted in boldface in Listing 13.  Otherwise everything in Listing 13
is something that you have seen before.

Java source code for class GwtApp009

The Java source code for the new class named GwtApp009 is shown in
Listing 14.


Listing 14. Java source code for class GwtApp009.


/*File GwtApp009.java
Copyright 2007, R.G.Baldwin

Tested using J2SE 5.0, GWT version 1.1.10, 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 GwtApp009 implements EntryPoint{

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

    //Instantiate a new ScrollPanel object.
    ScrollPanel topGui = new GwtApp.client.GwtApp009a();
    //Instantiate a new DoclPanel object.
    DockPanel bottomGui = new GwtApp.client.GwtApp009b();

    //Place the two objects in the user interface at the
    // locations of two paragraph elements having id
    // attributes with unique values.
    RootPanel.get("topComponent").add(topGui);
    RootPanel.get("bottomComponent").add(bottomGui);
    
  }//end onModuleLoad method
}//end class

The onModuleLoad method of this class instantiates objects
of the two new classes named GwtApp009a and
GwtApp009b and adds them to the user interface at the locations of
the two paragraph elements having id attribute values of topComponent and
bottomComponent respectively.

Java source code for class GwtApp009a 

The Java source code for class GwtApp009a is shown in Listing 15.


Listing 15. Java source code for class GwtApp009a.


/*File GwtApp009a.java
Copyright 2007, R.G.Baldwin

Tested using J2SE 5.0, GWT version 1.1.10, 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 GwtApp009a extends ScrollPanel{

  public GwtApp009a(){//constructor

    //Instantiate an HTML object that will serve as the
    // content for a ScrollPanel object.
    HTML content = new HTML(
      "<h3>GwtApp009a</h3>"
      + "<p>The purpose of this class is to illustrate "
      + "the following GWT programming concepts:</p>"
      + "<ol>"
      + "<li>Embedded style element in the host page.</li>"
      + "<li>Empty body in the host page.</li>"
      + "<li>Use of a scroll panel (without elaboration)"
      + "</li>"
      + "<li>Use of an HTML object</li>"
      + "</ol>"
      + "<p>The body of the host page is empty. This Java "
      + "code is compatible with an empty body in a host "
      + "page.</p>"
      + "<p>Tested using J2SE 5.0, GWT version 1.1.10, "
      + "and jakarta-tomcat-5.0.27 running as a localhost "
      + "server under WinXP. </p>");
      
    this.add(content);

    //Establish a name by which the CSS style material can
    // refer to this ScrollPanel object.
    this.setStyleName("scrollPanel");
    
  }//end constructor
}//end class

A modification of GwtApp006

This class was created by modifying the class named GwtApp006
The modification causes the new class to be one from which a new object can be instantiated by
a method in another class.

Most of the modifications made in the
upgrade are highlighted in boldface in Listing 15.  Note that the class
extends ScrollPanel and does not implement
EntryPoint.

Given the embedded
comments and the explanation of the modifications provided
earlier, you should have no problem
understanding everything in Listing 15.

Java source code for class GwtApp009b

The Java source code for class GwtApp009b is shown in Listing 16.


Listing 16. Java source code for class GwtApp009b.


/*File GwtApp009b.java
Copyright 2007, R.G.Baldwin

Tested using J2SE 5.0, GWT version 1.1.10, 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 GwtApp009b extends DockPanel{

  public GwtApp009b(){//constructor
    
    //Place an HTMLPanel containing explanatory text in the
    // north cell of this dock panel.
    HTMLPanel htmlPanelNorth = new HTMLPanel(
      "<h3>GwtApp009b - This sample application "
      + "illustrates the "
      + "construction of a composite user interface based "
      + "on several different types of components.</h3>");
    this.add(htmlPanelNorth,DockPanel.NORTH);

    //Instantiate a new HTMLPanel and populate it with a
    // list of hyperlinks to other web sites.  Add it to
    // the west cell of this dock panel.
    String content = 
      "<p><a href="http://www.dickbaldwin.com/toc.htm">"
        + "Table of Contents</a></p>"
      + "<ul>"
      + "<li><a href="http://www.dickbaldwin.com/"
        + "tocint.htm">Intro Java</a></li>"
      + "<li><a href="http://www.dickbaldwin.com/"
        + "tocmed.htm">Intermediate Java</a></li>"
      + "<li><a href="http://www.dickbaldwin.com/"
        + "tocadv.htm">Advanced Java</a></li>"
      + "<li><a href="http://www.dickbaldwin.com/"
        + "tocknowledge.htm">Test Java Knowledge</a></li>"
      + "<li><a href="http://www.dickbaldwin.com/"
        + "tocjscript1.htm">JavaScript</a></li>"
      + "<li><a href="http://www.dickbaldwin.com/"
        + "tocdsp.htm">DSP</a></li>"
      + "</ul>";
    HTMLPanel htmlPanelWest = new HTMLPanel(content);
    this.add(htmlPanelWest,DockPanel.WEST);
    
    //Place a large image in a small scroll panel and place
    // the scroll panel in the center cell of this dock 
    // panel.
    Image image = new Image("pool.jpg");
    ScrollPanel scrollPanel = new ScrollPanel(image);
    scrollPanel.setStyleName("scrollPanel");
    this.add(scrollPanel,DockPanel.CENTER);
    
  }//end constructor
}//end class

A modification of GwtApp008

This class was created by modifying the class named GwtApp008
Once again, the modification causes the new class to be one from which a new
object can be instantiated by a method in another class.

Most of the modifications made in the
upgrade are highlighted in boldface in Listing 16.  Note that the class
extends DockPanel and does not implement
EntryPoint.

Given the embedded
comments and the explanation of the modifications provided
earlier, you should have no problem
understanding everything in Listing 16.

Run the program

That concludes the presentation and explanation of new material in this
lesson. 

I encourage you to download and install the GWT framework and the Jakarta
Tomcat server (see Download) and to
use those products to replicate the applications and the results that I have
presented in this lesson.

Modify the source code in the Java files and the HTML host pages that are
produced by the GWT applicationCreator.  Experiment with that code by compiling
your modified web applications and observing the impact of your changes.

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

Summary

In this lesson, I showed you how to control the layout of a GWT Ajax web
application using HTML layout capabilities.  Then I showed you how to
control the layout using several of the layout classes in the GWT API. 
Finally, I showed you how to control the layout using a combination of the two.

In addition, I taught you some essential aspects of the creation and
deployment of GWT Ajax web applications that I was unable to include in the
first lesson in the series.

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, 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 event
driven programming.

Complete program listings


Complete listings of all of the programs discussed in this lesson were provided
intact as embedded listings in the text of the lesson.  Therefore, contrary
to my normal practice, this section does not contain program listings.

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