DOC

How to create a Google Web Toolkit widget using the Dojo Framework

By Edward Davis,2014-08-28 23:19
7 views 0
How to create a Google Web Toolkit widget using the Dojo Framework

    Objet Direct

    Tatami

    How to create a Google Web Toolkit

    widget using the Dojo Framework

    Auteur : Henri Darmet, Vianney Grassaud

    Version : 1.1

    December 2007

    Objet Direct Lyon 1 cours Albert Thomas 69003 Lyon Tél 04 72 33 78 30 Fax 04 72 33 68 67 Objet Direct Grenoble Les Iles Cordées 38113 Veurey Tél 04 76 53 72 72 Fax 04 76 53 72 77 Siège : 39 rue des Peupliers 92100 Boulogne Tel 01 56 88 69 00 Fax 01 56 88 69 01 SAS au capital de 160 000 ?. Siret 433 914 322 722 Z

    www.objetdirect.com

    Objet Direct

    How to create a Google Web Toolkit widget using the

    Dojo Framework

    1. HOW TO CREATE A GOOGLE WEB TOOLKIT WIDGET USING THE DOJO FRAMEWORK ..3 1.1. DOJO INTEGRATION ..............................................................................................................3 1.2. INTERNALS OF TATAMI (GWT/DOJO) WIDGETS ........................................................................4 1.2.1. Presentation ...................................................................................................................4 1.2.2. Life cycle ........................................................................................................................5 1.2.3. DOM shell element (and GWT events capture) ...............................................................5 1.2.4. Be friendly with the Garbage Collector ............................................................................6 1.2.5. Avoid memory leaks .......................................................................................................8 1.3. A COMMENTED EXAMPLE: THE FISHEYE ..................................................................................8 1.3.1. To start ..........................................................................................................................8 1.3.2. Add active icons ........................................................................................................... 13 1.3.3. Capturing selection events ........................................................................................... 16 1.3.4. Some other little enhancements … ............................................................................... 17 1.4. AS A CONCLUSION: HOW TO CREATE A TATAMI WIDGET THAT WRAPS A DOJO WIDGET ................ 17 1.4.1. Create a Tatami class .................................................................................................. 18 1.4.2. Ask for Dojo Script loading ........................................................................................... 18 1.4.3. Define a constructor that partially build the widget ........................................................ 18 1.4.4. Define simplified constructors ....................................................................................... 19 1.4.5. Redefine “onAttach” and “onDetach” methods .............................................................. 20 2. TOOLS TO WRAP DOJO WIDGETS. ...................................................................................... 21 2.1. THE INTERFACE ? HASDOJO ?. ............................................................................................ 22 2.2. AN ? HELPER ? : DOJOCONTROLLER ................................................................................... 23 2.3. USE ABSTRACT CLASSES TO FACTORISE THE CODE OF TATAMI COMPONENTS. ........................... 26 2.3.1. The abstract classes proposed by Tatami. .................................................................... 26 2.3.2. An example detailed. .................................................................................................... 26 2.4. THE NEW FISHEYE CLASS. ................................................................................................... 29

    Version 1.1 - 2 -

    Objet Direct

    How to create a Google Web Toolkit widget using the

    Dojo Framework

    1. How to create a Google Web Toolkit widget using the

    Dojo Framework

    The goal of the Tatami project is to deliver a rich and amazing set of components for the Google Web Toolkit, using well known JavaScript libraries. The most impressive of these libraries is certainly the Dojo framework (www.dojotoolkit.org). Dojo contains today a large set of resources which a great part can be reused in Google Web Toolkit applications. And because direct use of Dojo (JavaScript programming) is very hard, this solution is particularly interesting. Indeed, Dojo is a complicated framework, poorly documented, and its APIs may change at any time! Tatami is a good (if not the best) solution to hide this complexity and to protect projects against Dojo unstable nature.

    1.1. Dojo Integration

    To integrate Dojo in the Google Web Toolkit, the following steps are required:

    ; First, GWT module is created,

    ; Second, Dojo is installed inside this module

    ; Eventually, Dojo is declared in the module configuration file

    I don’t explain here how to create a GWT module. There are numerous tutorials, documentation and books that explain this with great details, counting mine which is accessible in Objet Direct Wiki (unfortunately, in French only)

    The second task is the Dojo installation inside the module. This is done by copying the “dojo.js” script file and the “src” folder, from the Dojo distribution to the “public” folder of your GWT module (a GWT module is constituted by three folders : client, server and public). The “src” folder contains numerous JavaScript file loaded when necessary, by the Dojo bootstrap.

    If the version of your GWT distribution is older than 1.4, you must append the following line at the end of the “dojo.js” file :

function dojoIsOk() {}

    This function is necessary for the Google Web Toolkit page loader to ensure that the Dojo bootstrap file (i.e. “Dojo.js”) is completely loaded before your application is started.

    The last step is to declare Dojo in the module configuration file (the file within the “public” folder and which extension is “.gwt.xml”). This is done by inserting the

    following lines:

    Version 1.1 - 3 -

    Objet Direct

    How to create a Google Web Toolkit widget using the

    Dojo Framework

src="dojo.js">

     if ($wnd.dojoIsOk)

     return true;

     else

     return false;

     ]]>

    Note that if the GWT version is 1.4 or newer, only a shorter declaration is required:

src="dojo.js" />

    1.2. Internals of Tatami (GWT/Dojo) widgets

    1.2.1. Presentation

    A classical GWT widget is constituted by an envelope (the widget object itself) and a DOM object. The DOM object is the only one recognized by the navigator. For GWT, the DOM object is an opaque JavaScript object. This DOM object is handled using helper methods declared in the DOM class (package com.google.gwt.user.client). The envelope object is a Java Object and must be an instance of a sub class of Widget (same package). This Java Object drives the DOM object.

    This structure implies that GWT handles two component trees: one for GWT widget and one for DOM objects. The two trees are related, and must remain consistent. The widget tree is build programmatically (and this built is often the main part of a GWT application). The DOM tree is constructed and maintained by the widgets.

    When Dojo is used, this structure is a little bit more complicated, because Dojo needs another component structure! Indeed, Dojo uses a principle similar to the one described before: Dojo envelope objects are used to handle DOM objects. The envelope objects are Dojo widgets. These widgets, like their GWT counterparts, cannot render directly to the screen (Only DOM objects can). Theses widgets are JavaScript objects, and cannot be used directly as GWT widgets. The internal Dojo structure is not really a tree. It is more a registry, a kind of pool of widgets, not necessarily linked together. The important point to remember is that when a widget is not used any more, it must be explicitly destroyed, in order to be unregistered from the Dojo and so, removed from memory.

    The master object in this hybrid component structure is the GWT widget (called thereafter the Tatami widget). It’s to this widget to create the Dojo widget which in turn creates the DOM object. At last, the Tatami widget retrieves the DOM object from the Dojo widget (and don’t create one like in the classical scheme). The Tatami widget keeps a link to the Dojo widget, because it needs this widget in order to drives safely the DOM object. Eventually, the Tatami widget must destroy the Dojo Widget.

    Version 1.1 - 4 -

    Objet Direct

    How to create a Google Web Toolkit widget using the

    Dojo Framework

    1.2.2. Life cycle

    In fact, the Tatami widget and the Dojo widget are heavily coupled. The best solution would have to synchronize their life cycles : when the Tatami widget is created, it creates immediately the Dojo widget. When the Tatami widget is discarded, it destroys the Dojo one.

    But there is an issue : In JavaScript, the destruction of an object cannot be intercepted like in Java using the finalize method. So, the destruction of a GWT widget cannot be used to call the destruction of the Dojo one.

    The only reliable events in the GWT/Tatami widget lifecycle which can be used are the attachment and the detachment of the widget into (or from) the widget tree. Tatami uses these events to manage the lifecycle of the Dojo widget (and associated DOM elements).

    The Tatami widget delays the construction of the Dojo widget until it is inserted in the widget tree. This happens when the “onAttach” method is invoked on the Tatami widget. Do the construction of the Dojo widget is done inside this method. Conversely the Dojo widget is destroyed inside the “onDetach” method invocation.

    1.2.3. DOM shell element (and GWT events capture)

    There is another issue, which can be transformed in an advantage: during GWT widget creation (thus Tatami widget creation), a DOM element must be created and associated to the widget. But at that moment, the Dojo widget doesn’t exist. Unfortunately, the needed DOM element is not available so early because it’s to the

    Dojo widget to create the DOM structure.

    To solve this issue, the Tatami widget created a basic DOM element without any rendering effect. Generally, this DOM element is a DIV one. The widget attaches the element as its root DOM element. When the Tatami widget is “attached” (i.e. inserted

    into the widget tree), it creates the Dojo widget as explained before. Then, it ask the Dojo widget to get its “domNode”. This “domNode” refers the root DOM element created by the Dojo widget. Eventually, this “domNode” element is inserted at the bottom of the DIV element.

    Version 1.1 - 5 -

    Objet Direct

    How to create a Google Web Toolkit widget using the

    Dojo Framework

    This craftiness has another advantage. It simplifies the standard management of events. Tatami uses this shell element (i.e. the DIV element) to capture GWT UI events (mouse event for example) and to send them to listeners in the usual way. This makes the framework more robust. Indeed, it’s very difficult to inject directly JavaScript into DOM elements created by Dojo. Using the shell element, this risky task is not needed any more.

    1.2.4. Be friendly with the Garbage Collector

    The Tatami Widget and its associated Dojo widget work together. The Tatami widget requests the Dojo widget every time something must be updated in the DOM tree. So, the Tatami widget holds a reference to the Dojo one.

    But a reverse link, owned by the Dojo widget is also necessary. It’s used to call back methods when a UI event occurs. DOM elements which interact with the user are triggered to call Dojo widget methods, not Tatami widget methods. It’s to the Dojo

    Version 1.1 - 6 -

    Objet Direct

    How to create a Google Web Toolkit widget using the

    Dojo Framework

    widget to forward these calls to the Tatami widget. So a reference to the Tatami widget is also needed.

And, of course, there is an issue;. In “hosted mode” (i.e. development mode),

    Tatami widgets and Dojo widget live in different worlds. Tatami widgets are Java objects managed by the JVM. Dojo widgets remain JavaScript objects and are managed by the JavaScript runtime.

    The border between these two worlds is JSNI, the JavaScript interface defined by GWT, and based on JNI. And J(S)NI is not truly compatible with garbage collector of each side. Even, if Java and JavaScript object pair constitutes a disconnected cycle, they cannot be removed because references to each others, cross JSNI.

    To avoid this problem, the reference pair must be broken. The best place to break it is the “onDetach” method seen earlier. The method onDetach of the widget Tatami sets to null its reference towards the widget Dojo after having asked for its destruction. It also nullifies the gwtWidget attribute (of the Dojo widget). Resetting

    Version 1.1 - 7 -

    Objet Direct

    How to create a Google Web Toolkit widget using the

    Dojo Framework

    these references is mandatory: asking for purely logical destruction of the Dojo widget, is not enough to remove the JavaScript object from memory.

    1.2.5. Avoid memory leaks

    But this is not sufficient to save us from JavaScript memory leaks. There are cases, where JavaScript creates memory leaks. We must avoid them systematically. The most common example is closure. Closures are often used to define methods that trigger UI events. Tatami takes a great care to never use closure.

    1.3. A commented example: the FishEye

    FishEye is a command Dojo widget. It renders as a bar of icons. These icons increase when the mouse approaches them. The closer the mouse is, the bigger the size of the. As soon as an icon is clicked, the command associated with the icon is executed.

    The FishEye is one of the most popular Dojo component. It was the first component which was integrated in Tatami.

    1.3.1. To start

    The first thing to do is to create a Java class which extends the Widget class (package com.google.gwt.user.client.ui). It’s also possible to extend from a derived class like AbstractPanel. In our case this is not necessary, the Widget class is enough. This class must declare as many attributes as there are parameters needed by the Dojo widget construction. As the Dojo widget will be built after the construction of the Tatami widget ended, it is necessary to keep the values of these parameters inside the Tatami widget.

public class FishEye extends Widget {

     int itemWidth;

     int itemHeight;

     int itemMaxWidth;

     int itemMaxHeight;

     String orientation;

     int effectUnits;

     int itemPadding;

     String attachEdge;

     String labelEdge;

     boolean enableCrappySvgSupport;

     boolean conservativeTrigger;

    Version 1.1 - 8 -

    Objet Direct

    How to create a Google Web Toolkit widget using the

    Dojo Framework

I would not comment on the signification and utility of these attributes. It doesn’t

    matter here. I guess you to read the user guide for a detailed description. It is enough

    to know here that these values are the exact counterpart of the values given to the

    FishEye when it is built.

    The main Tatami Widget constructor just keeps the values in its internal state.

public FishEye(

     int itemWidth,

     int itemHeight,

     int itemMaxWidth ,

     int itemMaxHeight,

     String orientation,

     int effectUnits,

     int itemPadding,

     String attachEdge,

     String labelEdge,

     boolean enableCrappySvgSupport,

     boolean conservativeTrigger)

     {

     super();

     this.itemWidth = itemWidth;

     this.itemHeight = itemHeight;

     this.itemMaxWidth = itemMaxWidth;

     this.itemMaxHeight = itemMaxHeight;

     this.orientation = orientation;

     this.effectUnits = effectUnits;

     this.itemPadding = itemPadding;

     this.attachEdge = attachEdge;

     this.labelEdge = labelEdge;

     this.enableCrappySvgSupport = enableCrappySvgSupport;

     this.conservativeTrigger = conservativeTrigger;

     Element rootDiv = DOM.createDiv();

     DOM.sinkEvents(rootDiv, Event.ONMOUSEOVER);

     DOM.setEventListener(rootDiv, this);

     this.setElement(rootDiv);

     loadDojoFishEye();

     }

It also builds a basic DIV element. This element is attached to the Widget. The

    reason why such element is built and attached to the widget is explained earlier.

Call to DOM.sinkEvents and DOM.setEventListener are necessary to fix a bug of the

    Dojo FishEye implementation (unfortunately there are some;). For other Dojo

    Widget wraps, these calls should not be useful.

Look at the last line : there is a call to “loadDojoFishEye”. This call is needed. It must

    be systematically done (just changing the method name for other wrappings). This

    Version 1.1 - 9 -

    Objet Direct

    How to create a Google Web Toolkit widget using the

    Dojo Framework

    call asks for partial Dojo script (FishEye implementation only) loading. This operation is implemented in two methods:

    ; A Java method verifies that theses scripts are not already loaded.

    ; A JavaScript method (i.e. a JSNI method to be precise), invoked by the

    previous Java method, really does the stuff.

The Java method is given here :

protected static void loadDojoFishEye() {

     if (!dojoFishEyeLoaded) {

     doLoadFishEye();

     dojoFishEyeLoaded = true;

     }

     }

     static boolean dojoFishEyeLoaded = false;

The JavaScript (JSNI) method is the following one :

protected static native void doLoadFishEye()

     /*-{

     $wnd.dojo.declare("dojox.widget.TatamiFisheyeItem",

     $wnd.dojox.widget.FisheyeListItem, {

     onClick:function (e) {

    this.parent.gwtWidget.@com.objetdirect.tatami.client.FishEye::dispatchClick(Ljava/lang/String;)(this.iconSrc);

     }});

     }-*/;

The Java method is trivial. It just calls the JavaScript method if it hasn’t do it before.

    The content of the JavaScript method is more interesting. There are two parts: the first one asks for a script loading. The second one creates a new Dojo Widget class.

    Script loading deals with Dojo scripts which implements the FishEye (FisheyeList.js file contained in the “widget” folder. This folder is included in the “src” folder of the

    Dojo distribution).

    With the creation of a new class of widget, we define once for all, how the Dojo widget is wired to the Tatami widget. We will explain this feature later, with more details.

    Version 1.1 - 10 -

Report this document

For any questions or suggestions please email
cust-service@docsford.com