August 1, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Controlling layout in AJAX web applications using the GWT and Java

  • January 2, 2007
  • By Richard G. Baldwin
  • Send Email »
  • More Articles »

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






Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel