gamelan
Search EarthWeb
CodeGuru | Gamelan | Jars | Wireless | Discussions
Navigate developer.com
Architecture & Design  
Database  
Java
Languages & Tools
Microsoft & .NET
Open Source  
Project Management  
Security  
Techniques  
Voice  
Web Services  
Wireless/Mobile
XML  
Technology Jobs  

   Developer.com Webcasts:
  The Impact of Coding Standards and Code Reviews

  Project Management for the Developer

  Defining Your Own Software Development Methodology

  more Webcasts...




See the Winners!


Developer Jobs

Be a Commerce Partner
Promotional Products
Home Improvement
Server Racks
Condos For Sale
Hurricane Shutters
GPS Devices
Boat Donations
Prepaid Phone Card
Promote Your Website
Build a Server Rack
Disney World Tickets
Best Price
Corporate Awards
Compare Prices

 
PDAs
PC Notebooks
Printers
Monitors

Click Here
  Rethinking the Datacenter
Sponsored by HP
Today's datacenters need to increase utilization, get control over power and cooling costs, and align with business objectives. Download this eBook to learn about the challenges facing the data center in a world where digital information is growing at a torrid pace and costs are being held in check. Learn more. »
 
  Putting the Green into IT
Sponsored by HP
Electricity use in data centers is skyrocketing, sending energy bills through the roof, creating environmental concerns and generating negative publicity. "Going Green" means looking to technologies like virtualization, energy-efficient chips and racks, and implementing policies that extend beyond the data center. Learn more. »
 
  Managing the Modern Network
Sponsored by HP
In a global economy where information crosses the globe in an instant, and where Web-based applications power business, it's more important than ever to ensure your network is safe from threats and optimized to deliver the data your business needs. »
 
  Evaluating Software as a Service for Your Business
Sponsored by Webroot
Is Software as a Service just hype, or is something really going on here? See if your company can benefit as SaaS tries to change the face of the enterprise. »
 
  Is Your Disaster Recovery Plan Good Enough?
Sponsored by HP
Preparing for a disaster is more often than not part of the storage planning process, and it is one of the most difficult tasks, since it includes local hardware and software, networking equipment, and a test plan. Learn how to get disaster recovery right. »
 
Related Article -
Event Driven Programming in AJAX Using the GWT and Java
Controlling layout in AJAX web applications using the GWT and Java
Developer News -
SaaS Tool Offers Custom Database Development    May 9, 2008
Microsoft’s Automated Agent: Can We Talk?    May 7, 2008
Borland Finally Sells CodeGear    May 7, 2008
Red Hat Heads For The JON 2.0    May 7, 2008
Free Tech Newsletter -

Best Practices for Developing a Web Site: Checklists, Tips, Strategies & More. Download Exclusive eBook Now.

Using the DOM class in AJAX with the GWT and Java
By Richard G. Baldwin

Java Programming Notes # 2558


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, such as HTML, JavaScript, XML, ASP.NET, Java servlets, various scripting languages, etc.

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

The Google Web Toolkit (GWT)

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

Most of the client-side code for a GWT Ajax application can be written in Java.  There is no requirement to write JavaScript code.  As you will see in this lesson, however, it is sometimes necessary to think about the JavaScript code.

Fifth in a series

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

Purpose of the tutorial

The main purpose of the tutorial is to teach you how to write the Java code necessary to make effective use of the DOM class in the GWT.

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. Creating a DOM node using the GWT.
  • Figure 2. The application GUI at startup.
  • Figure 3. GUI after clicking the button.
  • Figure 4. GUI after clicking the button with Alt key depressed.
  • Figure 5. Button clicked with middle mouse button.
  • Figure 6. Application GUI for GwtApp022 at startup.
  • Figure 7. Application GUI after clicking the button once.
  • Figure 8. Application GUI after clicking the button twice.
  • Figure 9. GUI for DoubleClick01 after single-click on button.
  • Figure 10. GUI after double-click on button.
  • Figure 11. A basic problem in the GWT.
  • Figure 12. Application GUI at startup for GwtApp023.
  • Figure 13. Application GUI after clicking both buttons.
  • Figure 14. The state of focus of the top button.

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.

General background information

What is the DOM class and why should you care?

According to the javadocs on the GWT, the DOM class "... provides a set of static methods that allow you to manipulate the browser's Document Object Model (DOM). It contains methods for manipulating both elements and events."

Not a fun place to be

In truth, this is a class that you would probably just as soon not have to use, particularly if your strong suite is Java and not JavaScript.  Any time you have to use the DOM class, you probably have to think about HTML, JavaScript, or both.  However, you will probably encounter things that you need to do in your web applications that you can only do by using methods of the DOM class.

A requirement for drag-and-drop

For example, in the previous lesson entitled "Focus events, click events, and Drag-and Drop in AJAX using the GWT and Java" (see Resources), it was necessary to invoke the setCapture method of the DOM class to make certain that the mouse would not lose the button as the button slid underneath another component while the button was being dragged.  I don't know of any way to accomplish that in the GWT without using a method of the DOM class.

Would prefer not to have to think about JavaScript or HTML

Usually when we are using Java and the GWT to develop a web application, we would usually prefer not to have to think about JavaScript or HTML.  However, it is not possible in some cases to totally ignore JavaScript and HTML.  Sometimes we have to think about them and do something that involves one or the other or both.  In reality, when a situation like that occurs, we usually need to do something that involves the Document Object Model (DOM) tree (see Resources) that represents the web page.

What is the DOM tree?

Instruction on the DOM tree is well beyond the scope of this tutorial, but you can read all about it on the W3C website (see Resources).  The DOM class in the GWT defines about ninety different static methods that you can use to manipulate the DOM tree in your web application.

Will discuss a subset of the available methods

Given that the DOM class contains such a large number of different methods, it won't be possible for me to teach you about all the capabilities that derive from those methods in this lesson.  However, I will teach you about five different capabilities that the methods support in different ways.  Hopefully, that will give you enough of a background on the topic that you can progress from there on your own.

Preview

Five GWT applications and one standard Java application

I will present and explain five sample GWT applications and one standard Java application in this lesson.  The names of the applications are shown in the following list.  This list also shows the primary topic that each application is designed to illustrate.

  • GwtApp019 - Creation of an HTML element or DOM node using the GWT.
  • GwtApp020 - Using the EventPreview capability to determine the state of the Alt key when a click event is fired
  • GwtApp021 - Determining which mouse button was pressed to cause a mouse event to be fired.
  • GwtApp022 - Dynamically controlling the style of GUI components at runtime.
  • DoubleClick01 - Illustrates the simplicity of single versus double-click event handling in standard Java.
  • GwtApp023 - Handling double-click events in the GWT.

Discussion and sample code

Complete program listings

I will discuss the code for the following applications in fragments.  A complete listing of each application is provided in Listing 23 through Listing 33 near the end of the lesson.

The HTML host pages

With one exception, the HTML host pages used for the applications in this lesson are essentially the same as those used for the applications in my earlier tutorials.  I will explain the one that is different, but I won't discuss the others in this lesson.  However, a complete listing of each HTML host page is also provided in Listing 23 through Listing 33 along with the Java source code for the application.

GwtApp019 - Creation of an HTML element or DOM node using the GWT

The purpose of this application is to demonstrate the use of a method of the DOM class to create of a new DOM node.  The application GUI is shown in Figure 1.

Figure 1. Creating a DOM node using the GWT.

Not a lot of fun.
Writing Java code to create HTML elements at runtime is not the most enjoyable way to spend your programming time.  However, as you can see in this application, such elements can be created at runtime and this capability is something that you may find useful in your web applications.  Although not demonstrated in this lesson, such elements can also be removed at runtime.  The DOM class provides methods for dynamically creating more than 25 different types of HTML elements at runtime.
As you will see shortly, the boldface line of text in Figure 1 was created from a static h3 element in the HTML host page.

A dynamically created paragraph

However, the paragraph below that header was not included in the HTML host page.  Rather, it was generated dynamically at runtime by the code in the GWT.

HTML host page for GwtApp019

The HTML host page for this application is shown in Listing 1.  An HTML comment shows the location at which the new element is created at runtime. Note that an ID attribute is assigned to the body element in the host HTML page to make it accessible to the Java code.  This is the only thing that makes this HTML host page different from most of the host pages that you have seen in earlier lessons.

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

</head>

<!--Assign an ID to the body element to make it accessible
by the Java code-->
<body id="rootNode">
<script language="javascript" src="gwt.js"></script>
<iframe id="__gwt_historyFrame" 
              style="width:0;height:0;border:0"></iframe>

<h3>GwtApp019</h3>

<!--A paragraph element will be placed here in the output 
HTML by the Java code-->


</body>
</html>

It may be possible to accomplish what this application accomplishes without a requirement to establish such an ID attribute, but it wasn't obvious to me how to do so.

Java code for GwtApp019

The Java source code for this application is shown in its entirety in Listing 2.

Listing 2. Java code for GwtApp019.
package GwtApp.client;

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

public class GwtApp019 implements EntryPoint{

  //This is the entry point method.
  public void onModuleLoad(){
    
    //Get a handle on the root node of the DOM tree.
    Element rootNode = DOM.getElementById("rootNode");
    
    //Text to be displayed in the paragraph element that 
    // will be generated using Java code.
    String para = "This paragraph element was generated "
                + "by the Java code.";
    
    //Create and populate the new paragraph element.
    Element pElement = DOM.createElement("<p>");
    DOM.setInnerText(pElement,para);
    
    //Append the new paragraph element to the DOM tree.
    DOM.appendChild(rootNode,pElement);
    
  }//end onModuleLoad method
  //====================================================//

}//end class GwtApp019

Get a handle on the root node

The source code begins by using a static method of the DOM class named getElementById to get and save a handle on the root node of the DOM tree (the body element)

Create and populate a new paragraph element

Then it uses the following two static methods of the DOM class to create and populate a new paragraph element.

  • createElement
  • setInnerText

Manipulating nodes in DOM tree.
There are several methods in the DOM class that make it possible for you to manipulate the nodes in the DOM tree in various ways.
Append the new element to the DOM tree

Finally, it uses a static method of the DOM class named appendChild to append the new node (the new paragraph element) to the DOM tree.

When the application is executed, the new paragraph element is created and displayed as shown in Figure 1.

Testing

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

GwtApp020 - Determining the state of the Alt key when a click event is fired

The event preview capability

This application will introduce you to a very important capability made available to the GWT by the DOM class.  This is the capability to preview events before they are handled by registered event handlers and possibly to intervene in some way before they are handled.  This capability will be used extensively in the subsequent applications in this lesson.

What key or keys were pressed?

Sometimes you need to know whether the user was holding down the Alt key, the Shift key, or the Ctrl key when an event is fired.  This application will teach you how to use the event preview capability to determine the state of the Alt key when a click event is fired.  You should be able to extend that knowledge to cover the Shift key and the Ctrl key on your own.

The application GUI at startup

Figure 2 shows the application GUI at startup, before the user clicks the button with the mouse.

Figure 2. The application GUI at startup.

As you can see, the label at the bottom displays the default text "Startup."

GUI after clicking the button

Figure 3 shows the GUI after the user has clicked the button with the mouse.

Figure 3. GUI after clicking the button.

At this point, the label at the bottom indicates that the Alt key was not depressed when the click event was fired.

GUI after clicking the button with Alt key depressed

Figure 4 shows the GUI after the user has clicked the button with the mouse while holding down the Alt key.

Figure 4. GUI after clicking the button with Alt key depressed.

In this case, the label at the bottom indicates that the Alt key was depressed when the click event was fired.  This demonstrates that it is possible to determine if the Alt key is being held down when a click event is fired.  Although it won't be demonstrated in this lesson, as mentioned earlier, similar code can be used to determine if the Shift key or the Ctrl key is depressed when a click event is fired.

Description of the application

As mentioned earlier, the purpose of this application is to introduce the event preview capability of the DOM class.  An object of a class that implements the EventPreview interface is registered using a static method of the DOM class to preview all events.  When an event is fired in this application, a reference to the event is saved in an instance variable named theEvent.  This reference is used later by the onClick method of a ClickListener object registered on a GUI button to determine the state of the Alt key when the click event was fired.

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

Beginning of the class definition

The class definition for GwtApp020 begins in Listing 3.

Listing 3. Beginning of the class definition for GwtApp020.
package GwtApp.client;

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

public class GwtApp020 implements EntryPoint{
  //The contents of this label are modified by the onClick
  // method when the user clicks a GUI button.
  Label label = new Label("Startup");
  
  //The following variable is used to store a reference to
  // each event that is fired.  When the GUI button fires
  // a click event, this reference is used to determine
  // the state of the Alt key when the user clicked the
  // GUI button with the mouse.
  Event theEvent;

  public void onModuleLoad(){
    //Instantiate a new Button object and register a click
    // listener on it.
    Button button = new Button("Click Me");
    button.addClickListener(new ClickLstnr());

The code in Listing 3 is straightforward and shouldn't require an explanation beyond that provided by the comments.

Register an EventPreview listener object

Listing 4 uses a static method of the DOM class to register an EventPreview listener object.

Listing 4. Register an EventPreview listener object.
    DOM.addEventPreview(new EventPrevue());

Register it on what?

Normally when we register a listener object, we register it on a specific component.  As you can see from Listing 4, however, this listener object isn't being registered on any specific component.  I suppose we might say that it is being registered on the entire application.  In any event, the EventPreview listener will have an opportunity to preview all events fired anywhere in the application before they are delivered to listener objects that are registered on specific components.

Add the GUI button and the label to the RootPanel

Listing 5 completes the onModuleLoad method by adding the button and the label to the RootPanel as shown in Figure 2.

Listing 5. Add the GUI button and the label to the RootPanel.
    RootPanel.get().add(button);
    RootPanel.get().add(label);
    
  }//end onModuleLoad method

An EventPreview listener class

Listing 6 defines an inner (member) listener class that implements the EventPreview interface.

Listing 6. An EventPreview listener class.
  class EventPrevue implements EventPreview{
    public boolean onEventPreview(Event event){
      theEvent = event;
      return true;//Don't cancel the event.
    }//end onEventPreview
  }//end class EventPrevue

Recall that an object of this class is registered on the application using a static method of the DOM class to preview all events in Listing 5.

Save a reference to the Event object

When any event is fired within the application, a reference to the event is saved in the instance variable named theEvent by the code in Listing 6.  This reference is used later by the onClick method of a ClickListener object to determine and display the state of the Alt key when the event was fired.

Don't cancel the event

The onEventPreview method in Listing 6 returns true to prevent the event from being cancelled.  If the method were to return false, the event would be cancelled and would not be delivered to the ClickListener object that is registered on the GUI button.

An inner ClickListener class

Listing 7 defines an inner class that implements the ClickListener interface.

Listing 7. An inner ClickListener class.
  class ClickLstnr implements ClickListener{
    public void onClick(Widget sender){

      if(DOM.eventGetAltKey(theEvent)){
        label.setText("Alt key is down.");
      }else{
        label.setText("Alt key is up.");
      }//end else

    }//end onClick
  }//end class ClickLstnr

}//end class GwtApp020

An object of this class is registered on the GUI button in Listing 3.  When the user clicks the GUI button with the mouse, the code in this event handler uses a static method of the DOM class named eventGetAltKey along with the reference to the event that was saved during the event preview process to determine and display the state of the Alt key when the event was fired.  The text in the label is set to reflect the state of the Alt key as shown in Figure 3 and Figure 4

Testing the Shift and Ctrl keys

In addition to the method named eventGetAltKey, the DOM class also defines the following static methods that can be used to determine the state of the Ctrl key and the Shift key when any event is fired:

  • eventGetCtrlKey
  • eventGetShiftKey

End of the class

Listing 7 also signals the end of the GwtApp020 class and the end of the discussion of the application having the same name.

GwtApp021 - Determining which mouse button was pressed when a mouse event is fired

While describing the drag-and-drop sample application in the lesson titled "Focus events, click events, and Drag-and Drop in AJAX using the GWT and Java" (see Resources) I identified a potential problem.  I told you that the GUI button could be dragged across the screen by pressing any of the three mouse buttons on the GUI button to execute the drag operation.

That is not normally how we would want a web application to behave.  Normally, we would want to reserve the drag operation for a specific mouse button and use the other two mouse buttons for other purposes.  This, of course, requires you to be able to write your code in such a way that it knows which mouse button was pressed.  That is the main topic of this application.

The application GUI

Figure 5 shows the result of clicking the large GUI button with the middle mouse button.

Figure 5. Button clicked with middle mouse button.

Label identifies the mouse button

As you can see, the label at the bottom reports on which mouse button was pressed to cause the event to be fired.  Clicking the GUI button with the left or right mouse buttons cause a similar report to appear in the label, except that the corresponding mouse button is identified in the label.

Description of the application

The purpose of this application is to demonstrate the ability to determine which mouse button was pressed when a mouse event is fired.

An object of a class that implements the EventPreview interface is registered on the application using a static method of the DOM class to preview all events.  When any event is fired, a reference to the event is saved in an instance variable named theEvent.  This reference is used later by the onMouseDown method of a MouseListener object registered on the GUI button shown in Figure 5.  The purpose of the MouseListener object is to determine and to display which mouse button was pressed, causing the mouse event to be fired.

Recall that as standard Button object in the GWT is not capable of firing mouse events.  Therefore, the GUI button used in this application is a custom button (like the one in the earlier lesson titled "Focus events, click events, and Drag-and Drop in AJAX using the GWT and Java - see Resources) that knows how to fire mouse events.

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

The onModuleLoad method

The beginning of the class and the complete onModuleLoad method are shown in Listing 8.

Listing 8. The onModuleLoad method for GwtApp021.
package GwtApp.client;

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

public class GwtApp021 implements EntryPoint{
  //The contents of this label are modified by the 
  // onMouseDown method when the user clicks a GUI 
  // inputButton causing the inputButton to fire a mouse
  // event.
  Label outputLabel = new Label("Startup");
  
  //The following variable is used to store a reference
  // to each event that is fired.  When the GUI
  // inputButton fires a mouse event, this reference is
  // used to determine which mouse button was pressed.
  Event theEvent;

  public void onModuleLoad(){
    //Instantiate a new custom button object and register
    // a mouse listener on it. This custom button knows
    // how to fire mouse events.
    Button button = new Button("Mouse Me");
    button.setSize("100px","50px");
    FocusPanel inputButton = new FocusPanel(button);
    inputButton.setSize("100px","50px");
    
    //Cause the focus to skip the FocusPanel and go
    // straight to the button that is wrapped in the
    // FocusPanel.
    inputButton.setTabIndex(-1);
    
    //Register a mouse listener on the GUI inputButton.
    inputButton.addMouseListener(new MouseLstnr());

    //Use a static method of the DOM class to register an
    // EventPreview listener object.
    DOM.addEventPreview(new EventPrevue());

    //Add the GUI inputButton and the outputLabel to the
    // RootPanel.
    RootPanel.get().add(inputButton);
    RootPanel.get().add(outputLabel);
    
  }//end onModuleLoad method

There is nothing new in Listing 8, and the code is heavily commented.  Therefore, I won't discuss the code in Listing 8 further.

The EventPreview class

An inner listener class that implements the EventPreview interface is shown in Listing 9.

Listing 9. The EventPreview class.
  class EventPrevue implements EventPreview{
    public boolean onEventPreview(Event event){
      theEvent = event;
      return true;//Don't cancel the event.
    }//end onEventPreview
  }//end class EventPrevue

An object of this class was registered on the application in Listing 8, using a static method of the DOM class.  This listener object previews all events that are fired within the application.  When an event is fired, a reference to the event is saved in the instance variable named theEvent.  This reference is used later by the onMouseDown method to determine and display which mouse button was pressed to cause the event to be fired.  The onEventPreview method returns true in Listing 9 to prevent the event from being cancelled.

The MouseListener class

Listing 10 defines an inner listener class that implements the MouseListener interface.

Listing 10. The MouseListener class.
  class MouseLstnr extends MouseListenerAdapter{
    public void onMouseDown(Widget sender,int x,int y){
      int theMouseButton = DOM.eventGetButton(theEvent);
      if(theMouseButton == Event.BUTTON_LEFT){
        outputLabel.setText("Left Mouse Button");
      }else if(theMouseButton == Event.BUTTON_MIDDLE){
        outputLabel.setText("Middle Mouse Button");
      }else if(theMouseButton == Event.BUTTON_RIGHT){
        outputLabel.setText("Right Mouse Button");
      }else{
        outputLabel.setText("Don't Know");
      }//end else
    }//end onMouseDown
  }//end class MouseLstnr

}//end class GwtApp021

Register the listener on the GUI button

An object of this class is registered on the GUI button in Listing 8.  When the user clicks the GUI button shown in Figure 5 with the mouse, the code in this event handler uses a static method of the DOM class along with a reference to the Event object and constants defined in the Event class to determine and display an identification of the mouse button that was pressed to cause the event to be fired.

Otherwise, the code in Listing 10 is straightforward and shouldn't require additional explanation.

End of the class

Listing 21 also signals the end of the class named GwtApp021, and the end of the discussion of the application having the same name.

GwtApp022 - Dynamically controlling the style of GUI components at runtime

As you learned in an earlier lesson, you can control the style of GWT GUI components through the use of a style sheet.  That style sheet can either be embedded in the HTML host page, referenced by the HTML host page, or both.

In his application, you will learn that you can also control the style of GUI components dynamically at runtime through the use of Java code.  This makes it possible for the style of the components to change as a result of the firing of different events as the execution of the application progresses.

Application GUI at startup

Figure 6 shows the application GUI at startup.

Figure 6. Application GUI for GwtApp022 at startup.

As you can see, the text on the face of the button is colored red.

Application GUI after clicking the button once

Figure 7 shows the GUI after clicking the button once following startup.

Figure 7. Application GUI after clicking the button once.

Clicking the button once following startup causes the text on the face of the button to change from red to green as show in Figure 7.  Thus, the style of the button has been modified as a result of the click event fired by the button.

Application GUI after clicking the button twice

Figure 8 shows the GUI after clicking the button twice following startup.

Figure 8. Application GUI after clicking the button twice.

Clicking the button twice following startup causes the text to change from red to green, and then from green to blue.  Once again, this occurs as a result of the click events fired by the button.

Application GUI after clicking the button three times

Although I didn't show it here, clicking the button three times following startup causes the GUI to return to the state shown in Figure 6 with red text on the face of the button.  The third click event causes the text color to change from blue back to red.

Cycle colors among red, green, and blue

In other words, each click event fired by the button causes the text on the face of the button to change dynamically at runtime.  The changes in color trace out a repetitive pattern of red, green, blue, and back to red in that order.

Upper-case color values don't stick.
Note that even if you set the color style to #FF0000, it will later be found to have a value of #ff0000.  Therefore, any testing that is done on the hexadecimal values (when treated as a String) must use the lower-case representation of the hexadecimal values.
Description of the application

The purpose of this application is to use static methods of the DOM class to dynamically control the style of GUI components at runtime.

As shown in Figure 6, the application:

  • Instantiates a Button object.
  • Uses a static method of the DOM class to set its style to red.
  • Adds it to the root panel.

Then the application registers a click listener on the button that causes the text on the button to cycle through the colors of red, green, and blue each time the button is clicked.

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

Begin class definition for GwtApp022

Listing 11 shows the beginning of the class definition for GwtApp022.

Listing 11. Begin class definition for GwtApp022.
package GwtApp.client;

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

public class GwtApp022 implements EntryPoint{

  public void onModuleLoad(){
    //Instantiate a Button object, set its style to red,
    // and add it to the root panel.
    Button button = new Button("Button");
    DOM.setStyleAttribute(
                   button.getElement(),"color","#ff0000");
    RootPanel.get().add(button);

Attribute methods in the DOM class.
The DOM class contains a number of static methods that deal with attribute values including those in the following list:
  • getAtttribute
  • getBooleanAttribute
  • getIntAttribute
  • getIntStyleAttribute
  • getStyleAttribute
  • setAttribute
  • setBooleanAttribute
  • setIntAttribute
  • setIntStyleAttribute
  • setStyleAttribute
As you can see, after instantiating the Button object, the code in Listing 11 invokes the setStyleAttribute to set its "color" attribute to red (an attribute value of "#ff0000").

Method parameters

The three parameters to the setStyleAttribute method shown in Listing 11 are pretty interesting.  The javadocs describe them in order as:

  • The element whose style attribute is to be set.
  • The name of the style attribute to be set.
  • The style attribute's new value.

When you compare the last two parameters in Listing 11 with the descriptions of the parameters in the above list, the last two are pretty obvious.  The first one isn't so obvious, however.

Wrap your mind around this.
As I mentioned in an earlier lesson, the Java object of the Button class never really exists, because the Java source code is translated into JavaScript code before it is executed.  Because the Java source code is never compiled and executed under a Java virtual machine, the Java objects that I talk about in these lessons never really exist.
The getElement method

As you can see, Listing 11 invokes the getElement method on a reference to the button.  According to the javadocs, the getElement method "Gets a handle to the object's underlying DOM element."  In other words, this method makes it possible to manipulate the actual element in the DOM tree that is represented by the Java object of type Button.

Add the button to the root panel

After the button is instantiated and has had its style set in Listing 11, it is added to the root panel for display as shown in Figure 6.

Register a click listener on the button

Listing 12 shows the beginning of an anonymous inner class that registers a click listener on the button in order to cycle the color of the text through red, green, and blue each time the button is clicked.

Listing 12. Register a click listener on the button.
    button.addClickListener(
      new ClickListener(){
        public void onClick(Widget sender){
          //Get a reference to the element that
          // represents the button, and then get the
          // current value of the color style for that
          // element.
          Element element = sender.getElement();
          String attr = 
                   DOM.getStyleAttribute(element,"color");

Listing 12 gets a handle on the sender of the event as a DOM element, (which must be the button in this case).  Then it invokes the getStyleAttribute method, passing the element and the name of the style attribute of interest for the purpose of getting and saving the value of the attribute.

Cycle the colors

Listing 13 shows the remaining code for the anonymous inner class, from which a click listener object is instantiated and registered on the button.

Listing 13. Cycle the colors.
          if(attr.equals("#ff0000")){
            DOM.setStyleAttribute(
                               element,"color","#00ff00");
          }else if(attr.equals("#00ff00")){
            DOM.setStyleAttribute(
                               element,"color","#0000ff");
          }else{
            DOM.setStyleAttribute(
                               element,"color","#ff0000");
          }//end else
        }//end onClick
      }//end constructor
    );//end addClickListener
    
  }//end onModuleLoad method

}//end class GwtApp022

Listing 13 executes the logic that cycles the color style through red, green, and blue each time the button is clicked.  This code is straightforward and shouldn't require further explanation.

End of the class

Listing 13 also signals the end of the onModuleLoad method, the end of the class named GwtApp022, and the end of the discussion of the application having the same name.

DoubleClick01 - Illustrates the simplicity of single versus double-click event handling in standard Java

Now I'm going to show you something a little different.  The next (and last) topic of interest in this lesson has to do with being able to differentiate between single-click and double-click events.  I'm going to show you a standard Java application that illustrates the simplicity with which such differentiation can be accomplished in standard Java.  Following that, I will show you how to accomplish part of the same thing with the GWT, which as you will see isn't quite so simple.

GUI for DoubleClick01 after single-click on button

Figure 9 shows the application GUI after the user has performed a single-click on the button.

Figure 9. GUI for DoubleClick01 after single-click on button.

The label on the right in Figure 9 indicates that the event was a single-click event.

GUI after double-click on button

Similarly, Figure 10 shows the GUI after the user has performed a double-click on the button.

Figure 10. GUI after double-click on button.

As you can see, the program can differentiate between the two, and can take a different action depending on whether the event was a single-click event or a double-click event.

Beginning of the code for DoubleClick01

The code for the desktop application named DoubleClick01 begins in Listing 14.

Listing 14. Beginning of the code for DoubleClick01.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

class DoubleClick01 extends JFrame{

  public static void main(String[] args){
    new DoubleClick01();
  }//end main

The class named DoubleClick01 extends the JFrame class.  Hence, an object of the class is the program GUI.

The main method in Listing 14 instantiates an object of the DoubleClick01 class, thus creating the GUI and causing it to be displayed.

Beginning of the constructor

Listing 15 declares and initializes a couple of instance variables to create the button and the label shown in Figure 9.  Then Listing 15 shows the beginning of the constructor for the class.

Listing 15. Beginning of the constructor.
  Button button = new Button("Click me");
  Label label = new Label("Single-click");

  DoubleClick01(){
    setLayout(new FlowLayout());
    add(button);
    add(label);
    setSize(250,100);
    setTitle("Copyright 2006,R.G.Baldwin");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);

The constructor code in Listing 15 is straightforward, and should be self-explanatory on the basis of the names of the methods that are invoked to construct the GUI.

An anonymous mouse listener

Listing 16 defines, instantiates, and registers a MouseListener object on the button.

Listing 16. An anonymous mouse listener.
    button.addMouseListener(
      new MouseAdapter(){
        public void mouseClicked(MouseEvent event){
          switch(event.getClickCount()){
            case 1:label.setText("Single-click");break;
            case 2:label.setText("Double-click");break;
            default: label.setText("Don't know");
          }//end switch
        }//end mouseClicked
      }//end constructor
    );//end addMouseListener
  }//end constructor

}//end class DoubleClick01

Listing 16 uses a standard Java switch statement go determine whether the event was a single-click event or a double-click event and to display the results in the label as shown in Figure 9 and Figure 10.

The incoming parameter

Not so easy with the GWT.
As you will see later, the information necessary to differentiate between single-click and double-click events is not so easy to access in the GWT.
The critical thing about Listing 16 and the thing that makes this task so easy in standard Java (which is totally missing in the GWT) is the incoming parameter of type MouseEvent to the mouseClicked method.

Very little information in the GWT.
In comparison, the only incoming information to the onClick method in the GWT is a reference to the source of the event as type Widget.  As near as I have been able to determine, there is no incoming information about single versus double-click events.
This incoming parameter to the standard Java mouseClicked method is a reference to an object that encapsulates a lot of information about the event.  For example, the object encapsulates information that makes it almost trivial to determine if the event was a single-click or a double-click event.  All that is necessary to get that information is to invoke the getClickCount method on the incoming parameter.

A choice between two different actions

Listing 16 invokes the getClickCount method on the incoming parameter, and uses the information returned by that method to make a choice between two different actions.  Those two actions were purposely made very simple in this example program, but could be as simple or as complex as may be necessary to solve the problem at hand.  The important point is that it is easy to write the code necessary to make the choice.

Simple as 1-2-3.
I'm hoping that after this article is published, someone will contact me to tell me that I am completely wrong and show me how to differentiate between single-click and double-click events in the GWT.  If that happens, and if the approach isn't too overly complex, I will publish an update to this lesson on my web site giving that person credit for the information.
I can't make such a choice in the GWT

Quite frankly, I haven't figured out how to make such a choice in the GWT.  It can probably be done, but I haven't figured out how to do it, and so far, my research on the web hasn't led me to anything indicating that anyone else has figured out how to do it either (except for some Rube Goldberg-like approaches involving the use of a timer.)  Therefore, the next application that deals with the double-click event topic in the GWT will provide much less capability, (with quite a bit more code), than this simple application in standard Java.

GwtApp023 - Handling double-click events in the GWT

As near as I have been able to determine, the only way