Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Take a legacy path to advanced GWT controls

Integrate JavaScript libraries to enhance Google Web Toolkit widgets

Sergey Odobetskiy (s.odobetsky@gmail.com), Software development consultant , Freelance
Sergey Odobetskiy is a software development consultant specializing in Java and Web technologies. He has recently been involved in several telecom projects at Rogers Communications and is currently working in Toronto with ConceptWave Software Inc. on a telecom order-care product.

Summary:  The Google Web Toolkit (GWT) provides libraries and tools that let you develop Ajax applications in the Java™ programming language. Unfortunately, GWT's standard gallery of UI controls (widgets) doesn't provide the advanced features that modern enterprise applications require. This article shows a technique that addresses this deficiency. Find out how to give GWT controls advanced functionality with relatively simple coding by integrating a popular JavaScript grid component with a GWT application.

Date:  24 Apr 2007
Level:  Advanced
Also available in:   Chinese  Japanese

Activity:  18580 views
Comments:  

Open source Ajax frameworks and commercial toolkits try to make Ajax development more accessible by hiding complexity and the burden of low-level JavaScript and Document Object Model (DOM) operations. They often help to reduce development time, but using them to achieve advanced functionality usually requires a skill set and level of JavaScript knowledge that aren't trivial to acquire. Google has come up with innovative technology that brings Ajax application development to a completely new level. The GWT is a comprehensive set of APIs and tools that lets you create dynamic Web applications in Java code. GWT does this through code generation: The GWT compiler generates cross-browser compatible JavaScript from client-side Java code.

Unfortunately, the standard UI controls (widgets) Google offers have a limited feature set and in many cases cannot satisfy modern enterprise-grade applications. Although you can extend basic GWT controls with a set of custom properties, this path often requires significant development effort. Fortunately, an easier approach is available. With the help of a sample application (see Download), this article shows how to integrate the popular ActiveWidgets JavaScript grid component with a GWT application and achieve advanced functionality with relatively simple coding.

Dynamic Web UI controls

JavaScript Web UI controls are designed to eliminate server roundtrips by generating HTML dynamically inside the browser. Instead of sending static HTML, the server adds data structures and JavaScript code for the dynamic components into the page content. During page load, the browser runs the scripts to create active components, configures them, and then inserts the HTML string each component generates into the proper place on the page. From this point, the JavaScript component code is connected to the HTML fragment on the page. The component manages user interactions, updates the HTML according to the data changes, and provides an API to manipulate its content, behavior, and visual style.

GWT controls developed in Java code and compiled into JavaScript work exactly the same way. This makes them fully compatible with commercial controls and JavaScript libraries. JavaScript libraries are more mature and provide a complete set of cross-browser advanced features such as intelligent scrolling, column resizing, sorting, dynamic loading, and paging for large data sets. GWT's open architecture lets you integrate commercial controls and legacy JavaScript libraries with new applications and focus on solving enterprise challenges rather then reinventing the proverbial wheel.


Automatic resource injection

This article's sample GWT application (see Download) uses a handy GWT feature: automatic resource injection. A project module includes references to external JavaScript and Cascading Style Sheets (CSS) files, causing them to load automatically when the module itself is loaded. Listing 1 shows the declarations in the sample application's module-definition XML file (GridDemo.gwt.xml) that achieve this:


Listing 1. GWT module definition
                
<module>
  <inherits name='com.google.gwt.user.User'/>
  <entry-point class='com.mycompany.project.client.GridDemo'/>
  
  <source path="client"/>

  <stylesheet src="runtime/styles/xp/aw.css"/>
  <script src="runtime/lib/aw.js"> 
    <![CDATA[ 
     if ($wnd.AW.Grid.Control.create) 
       return true; 
     else 
       return false; 
   ]]> 
  </script>
</module>


Injection of JavaScript files and stylesheets is a convenient way to associate external files automatically with your GWT module. All injected resources must be placed in the com\mycompany\project\public directory, which defines the GWT Web server root.

AW.Grid.Control.create is a script ready-function that returns true when the grid-control script is known to be initialized. The ready-function's purpose is to determine unambiguously that the script is fully loaded so that your GWT code can use it and be sure the referenced identifiers are available. In the example in Listing 1, the existence of the AW.Grid.Control.create function indicates that the script is ready. This function is part of the control's library and as an external resource, it must be prefixed with $wnd.


JavaScript Native Interface to the rescue

Integration of the JavaScript grid control itself is based on GWT's implementation of the JavaScript Native Interface (JSNI), a powerful feature that lets you include JavaScript code in Java source code. Listing 2 shows how the JavaScript grid control is instantiated and initialized via JSNI:


Listing 2. Grid control initialization (fragment)
                

native JavaScriptObject init(JavaScriptObject myColumns,JavaScriptObject myData)/*-{
  try{
    $wnd.mygrid = new $wnd.AW.UI.Grid;
    $wnd.mygrid.setSize(750, 350);

    // provide cells and headers text
    $wnd.mygrid.setCellText(myData);
    $wnd.mygrid.setHeaderText(myColumns);

    // set number of rows/columns
    $wnd.mygrid.setRowCount(myData.length);
    $wnd.mygrid.setColumnCount(myColumns.length);
    ...
    $doc.getElementById('mygrid').innerHTML = $wnd.mygrid;

    return $wnd.mygrid;
  }
  catch(e){
    $wnd.alert(e.description);
  }

  return null;

}-*/;

JSNI can be considered the Web equivalent of inline assembly code. You can use it to:

  • Implement a Java method directly in JavaScript.
  • Wrap type-safe Java method signatures around existing JavaScript.
  • Call from JavaScript into Java code and vice versa.
  • Throw exceptions across Java/JavaScript boundaries.
  • Read and write Java fields from JavaScript.
  • Use hosted mode to debug both Java source (with a Java debugger) and JavaScript (with a script debugger).

The GWT development documentation warns that JSNI must be used with discretion because browser portability isn't guaranteed, and the compiled code optimization is restrictive. In the case of commercial controls, you can rely on the vendors' commitment to supporting multiple browser types and deployment platforms.

When you access the browser's window and document objects from JSNI, you must reference them as $wnd and $doc, respectively. Your compiled script runs in a nested frame, and $wnd and $doc are automatically initialized to refer correctly to the host page's window and document.

The sample code demonstrates a useful technique, using JSNI for converting one- and two-dimensional Java string arrays into JavaScript arrays to populate a grid with data, as shown in Listing 3:


Listing 3. Java-to-JavaScript array transformation
                
public static JavaScriptObject arrayConvert(String[] array) { 
    JavaScriptObject result = newJSArray(array.length); 
    for (int i = 0; i<array.length; i++) { 
      arraySet(result, i, array[i]); 
    } 
    return result; 
} 

private static native JavaScriptObject newJSArray(int length) /*-{ 
    return new Array(length);  
}-*/; 

public static native int arrayLength(JavaScriptObject array) /*-{ 
    return array.length; 
}-*/; 

public static native String arrayGetObject(JavaScriptObject array, int index) /*-{ 
    return array[index]; 
}-*/; 

public static native void arraySet(JavaScriptObject array,int index,String value) /*-{ 
    array[index] = value; 
}-*/;


Processing events

Event handlers defined in the JavaScript can be associated with methods implemented in your Java code. Listing 4 demonstrates how the grid control's onRowClicked event invokes the onRowSelect Java function:


Listing 4. Java function invocation from JavaScript
                
public void onRowSelect(String index){
  GWT.log("Row #" + index + "selected", null);
}

native JavaScriptObject init(JavaScriptObject myColumns, JavaScriptObject myData)/*-{
  var widget = this;
  
  try{
      ... 
      // set click action handler
      $wnd.mygrid.onRowClicked = function(event, index){

widget.@com.mycompany.project.client.GwtGrid::onRowSelect(Ljava/lang/String;)(index);
      };

      ...
 }
 catch(e){
  $wnd.alert(e.description);
 }
}-*/;

You must reference Java methods in JavaScript using the following notation: instance-expr.@class-name::method-name(param-signature)(arguments)

  • instance-expr. must be present when you call an instance method and must be absent when you call a static method.
  • class-name is the fully qualified name of the class in which the method is declared (or a subclass thereof).
  • param-signature is the internal Java method signature as specified here but without the trailing signature of the method return type (because it isn't needed to choose the overload).
  • arguments is the actual argument list to pass to the called method.

Using the JavaScript control API

As you can see from Listing 2, the init method of the implementation's Java class returns JavaScriptObject, which represents a grid instance. You can store it as a class attribute and reference it later in the code to invoke JavaScript control API methods. Listing 5 shows how a Delete button click event is processed in Java code:


Listing 5. JavaScript method invocation
                
protected JavaScriptObject grid = null;

...

public void onLoad(){
  if(grid == null){
    grid = init(...);
  }
}

public void onDeleteButtonClick(){
  delete(grid, getCurrentRow(grid));
}


public native void delete(JavaScriptObject obj, int index) /*-{

 try{
    obj.deleteRow(index);
 }
 catch(e){
    $wnd.alert(e.description);
 }

}-*/;	

public native int getCurrentRow(JavaScriptObject obj) /*-{
 
  try{
    return obj.getCurrentRow();
  }
  catch(e){
    $wnd.alert(e.description);
  }

  return -1;

}-*/;

In Listing 5, a Java event handler calls JavaScript control API methods. This demonstrates the ability to interact with the control instance. You can define similar Java wrappers for all JavaScript control API methods and make them available to the GWT world.


Runtime configuration

The demo application requires that you install the GWT SDK on your system. To run the sample code, simply unzip the downloaded archive with sources and compiled scripts into the GWT SDK distribution directory's samples folder. If you can run GWT samples, you can launch the sample application with following command (on Windows platforms):

                your_local_path\gwt-windows-1.3.3\samples\GridDemo\GridDemo-shell.cmd

The sample GWT application demonstrates integration of the commercial JavaScript grid component developed by ActiveWidgets and offered for evaluation download at company's Web site (see Resources). Figure 1 shows the result:


Figure 1. Advanced grid control in sample GWT application
Grid control in action

The demo application archive contains all required libraries except GWT. I've tested it with all major GWT releases, including version 1.3.


Conclusion

This article presents an example of how to integrate legacy JavaScript grid controls with GWT applications. You can use the same approach for other advanced controls available on the market. As an alternative to commercial JavaScript controls, check out the Yahoo! User Interface Library, an open source set of JavaScript utilities and controls for building richly interactive Web applications using techniques such as DOM scripting, DHTML, and Ajax (see Resources).



Download

DescriptionNameSizeDownload method
Sample GWT applicationj-gwtcontrols.zip503KB HTTP

Information about download methods


Resources

Learn

Get products and technologies

Discuss

About the author

Sergey Odobetskiy is a software development consultant specializing in Java and Web technologies. He has recently been involved in several telecom projects at Rogers Communications and is currently working in Toronto with ConceptWave Software Inc. on a telecom order-care product.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology, Web development
ArticleID=211854
ArticleTitle=Take a legacy path to advanced GWT controls
publish-date=04242007
author1-email=s.odobetsky@gmail.com
author1-email-cc=

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Special offers