 
 |
Download these IBM resources today!
e-Kit: IBM Rational Systems Development Solution
With systems teams under so much pressure to develop products faster, reduce production costs, and react to changing business needs quickly, communication and collaboration seem to get lost. Now, theres a way to improve product quality and communication.
Webcast: Asset Reuse Strategies for Success--Innovate Don't Duplicate!
Searching for, identifying, updating, using and deploying software assets can be a difficult challenge.
eKit: Rational Build Forge Express
Access valuable resources to help you increase staff productivity, compress development cycles and deliver better software, fast.
Download: IBM Data Studio v1.1
Effectively design, develop, deploy and manage your data, databases, and database applications throughout the data management life.
eKit: Rational Asset Manager
Learn how to do more with your reusable assets, learn how Rational Asset Manager tracks and audits your assets in order to utilize them for reuse.
|
|
 |
|
  |
|
|
|
|
|
|

Controlling layout in AJAX web applications using the GWT and Java
By Richard G. Baldwin
Java Programming Notes # 2552
Preface
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:
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.
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.
- 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.
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.
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.
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 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.
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.
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.
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 compon |