SlideShare une entreprise Scribd logo
1  sur  19
Télécharger pour lire hors ligne
Hochschule der Medien Stuttgart, Studiengang Medieninformatik




                 Das Google Webtoolkit

                                   von


                             Sven Pfleiderer


                     http://blog.roothausen.de
                          sven@roothausen.de

                             13. Januar 2011
Inhaltsverzeichnis

I.   Das Google Webtoolkit              4

1. Was ist GWT?                          4

2. Einsatzgebiete                        4

3. Applikationsstruktur                  4


II. UiBinder                             7

4. Aufgaben                              7

5. HTML und CSS im UiBinder              7

6. GWT-Objekte im UiBinder               8


III. JSNI                               10

7. Aufgaben                             10

8. Zugriff von Java auf JavaScript       11

9. Zugriff von JavaScript auf Java       11

10.JavaScriptObject                     12


IV. Deferred Binding                    14

11.Aufgaben                             14

12.Ersetzen f¨r einzelne Browser
             u                          14

13.Ersetzen f¨r eigene Properties
             u                          15




                                    2
V. History Management       17

14.Aufgaben                 17

15.History Tokens           17

16.History Handler          18


VI. Anhang                  19




                        3
Teil I.
Das Google Webtoolkit
1. Was ist GWT?
Das Google Webtoolkit[Ince] ist ein von Google entwickeltes Anwendungsframework zum
Erstellen von komplexen, sehr dynamischen Webanwendungen. Bei diesen Anwendun-
gen handelt es sich um Software, die direkt im Client, also im Webbrowser, ausgef¨hrt
                                                                                 u
wird. Diese Software kann hierbei komplett in Java entwickelt werden und wird von
GWT in, f¨r das Web typische, Formate wie HTML, JavaScript und CSS kompiliert.
         u
Grafische Elemente k¨nnen, ¨hnlich wie in anderen Java UI-Toolkits wie zum Beispiel
                   o      a
Swing oder AWT, komplett objektorientiert aufgebaut und verwendet werden. GWT-
Applikationen lassen sich zudem einfach in statische Webseiten oder bereits vorhandene
Webapplikationen integrieren.
  GWT enth¨lt zudem noch Werkzeuge, die die Entwicklungsarbeit stark vereinfachen.
          a
Darunter sind unter anderem Scripte um ein Grundger¨st einer Applikation zu erstellen
                                                   u
oder Plugins, die es erlauben Anwendungen “live” in einem Browser zu debuggen.


2. Einsatzgebiete
GWT kommt vor allem dort zum Einsatz, wo Webanwendungen m¨glichst dynamisch
                                                         o
und benutzerfreundlich sein sollen. Also an Stellen, an denen man von einer Webapplika-
tion erwartet, dass sie sich wie eine ¨quivalente Desktop-Applikation verh¨lt. Ziel ist es
                                      a                                   a
den Benutzer so wenig wie m¨glich durch Neuladen der Webseite aufzuhalten und einen
                              o
m¨glichst hohen Komfort in der Benutzung zu bieten. Es gibt mittlerweile sogar Projek-
 o
te, die GWT als Plattform f¨r webbasierte 3D-Spiele verwenden[ste]. Bei Google kommt
                           u
GWT vor allem bei Google Wave[Incd] und dem Google Adwords Control Panel[Incf]
zum Einsatz.


3. Applikationsstruktur
Eine GWT-Applikation besteht aus mindestens drei Komponenten: Einer HTML-Datei,
einer GWT.XML-Datei und einer Java Klasse. Diese Komponenten werden normalerwei-
se schon beim Erstellen eines neuen Projektes generiert und m¨ssen nur noch angepasst
                                                             u
und erweitert werden.



                                            4
Listing 1: Index.html
 1 <! doctype html >
 2 < html >

 3    < head >
 4    ...
 5       < title > Hello GWT </ title >
 6       < script type = " text / javascript "
 7          language = " javascript "
 8          src = " gwttest / gwttest . nocache . js " >
 9       </ script >
10    </ head >
11    < body >
12       < h1 > Hello GWT ! </ h1 >
13    < div id = " appcontainer " / >
14    </ body >
15 </ html >


       In in der HTML-Datei wird vor allem der JavaScript-Code eingebunden, der sp¨ter,
                                                                                  a
     je nach Browser, den entsprechenden Applikationscode einbindet. Die Aufgabe von *.no-
     cach.js Dateien besteht ausschließlich darin, den Browsertyp zu erkennen und anhand
     dieses Typs die entsprechenden *.cache.js-Dateien mit der konkreten Applikationslo-
     gik zu laden. Zudem wird in diesem Beispiel ein DIV-Element definiert. Dieses wird,
     wie sp¨ter beschrieben, GWT UI-Elemente aufnehmen. Durch die M¨glichkeit einzelne
           a                                                       o
     DIV-Elemente als Container f¨r GWT-Elemente zu verwenden, ist man in der Lage sta-
                                 u
     tische Webseiten zu erstellen und diese durch einbinden von GWT mit Zusatzfunktionen
     auszustatten.

           Listing 2: GWTTest.gwt.xml enth¨lt die Konfiguration des GWT Moduls
                                          a
 1 <? xml version = " 1.0 " encoding = " UTF -8 " ? >
 2 < module rename - to = ’ gwttest ’ >
 3    <! -- Inherit the core Web Toolkit stuff .                  -- >
 4    < inherits name = ’ com . google . gwt . user . User ’/ >
 5

 6     <! -- Inherit the default GWT style sheet .                 -- >
 7     < inherits name = ’ com . google . gwt . user . theme . standard . Standard ’/ >
 8

 9     <! -- Specify the app entry point class .                    -- >
10     < entry - point class = ’ de . roothausen . gwt . test . client . GWTTest ’/ >
11

12     <! -- Specify the paths for translatable code                -- >



                                               5
13    < source path = ’ client ’/ >
14 </ module >


         In den *.gwt.xml-Dateien werden mittels der inherits-Anweisung weitere GWT-Module
     geladen. Zudem wird die Java-Klasse bestimmt, die als Einstiegspunkt der Programm-
     logik dient. Werden weitere verwendete Java-Klassen in zus¨tzlichen Ordnern ben¨tigt,
                                                               a                    o
     k¨nnen Pfade definiert werden um diese zus¨tzlich einzubinden. In *.gwt.xml-Dateien
      o                                       a
     besteht zudem die M¨glichkeit Themes und Stylesheets zu definieren und einzubinden.
                        o
     Des Weiteren werden in diesen Konfigurationsdateien, wie in Teil IV beschrieben, die
     Definition von Deferred Binding vorgenommen.

                  Listing 3: GWTTest stellt den Einstiegspunkt der Applikation dar
 1   public class GWTTest implements EntryPoint {
 2

 3       public void onModuleLoad () {
 4         VerticalPanel container = new VerticalPanel () ;
 5         final Label helloLabel = new Label ( " Hello " ) ;
 6         Button helloButton = new Button ( " Change Text " ) ;
 7         container . add ( helloLabel ) ;
 8         container . add ( helloButton ) ;
 9

10           helloButton . addClickHandler ( new ClickHandler () {
11              @Override
12              public void onClick ( ClickEvent event ) {
13                helloLabel . setText ( " Button clicked " ) ;
14              }
15           }) ;
16           RootPanel . get ( " appcontainer " ) . add ( container ) ;
17       }
18   }

         Die eigentliche Programmlogik wird, wie bereits beschrieben, in Java definiert. Ver-
     ticalPanel, Label und Button sind hier GUI-Elemente aus dem GWT-SDK. Diese Ele-
     mente k¨nnen, wie in anderen Toolkits auch, miteinander kombiniert und anhand ihrer
            o
     Vererbungshierarchie verschachtelt werden: Das erstellte Panel nimmt das Label und
     den Button auf und wird vom GWT-Framework in das zuvor definierte DIV-Element
     eingef¨gt.
           u




                                                 6
Teil II.
    UiBinder
    4. Aufgaben
    Grundlegend bestehen GUI-Elemente von GWT-Applikationen ausschließlich aus HTML
    und CSS. Daher ist es nur nat¨rlich, feste und unver¨nderliche Bereiche der Webappli-
                                 u                      a
    kation auf genau dieser Abstraktionsebene definieren zu k¨nnen. Zudem ist es es sinnvoll
                                                            o
    dynamische GUI-Elemente in einer deklarativen Sprache zu definieren ohne diese uber
                                                                                  ¨
    Programmcode einzeln zusammen bauen zu m¨ssen. Diese Aufgaben werden durch das
                                               u
    UiBinder Framework abgebildet.


    5. HTML und CSS im UiBinder
    Der einfachste Anwendungsfall des UiBinders besteht darin, fixen HTML- und CSS-
    Code zu definieren, der neben dynamischen Inhalten in Anwendungen eigebaut werden
    kann. UiBinder Definitionen werden mit der Dateiendung .ui.xml abgespeichert. Norma-
    lerweise wird die passende UiBinder-Definition f¨r eine bestimmte Java-Klasse uber eine
                                                   u                             ¨
    Namenskonvention festgelegt. Im Falle der Klasse “HelloWorld.java” w¨rde automatisch
                                                                        u
    die UiBinder-Datei “HelloWorld.ui.xml” verwendet werden. Sollten sich die Namen der
    Java-Klasse und der UiBinder-Definition unterscheiden, kann innerhalb der Klasse mit
    Hilfe der @UiTemplate-Annotation explizit auf eine *.ui.xml-Datei verwiesen werden.

                                 Listing 4: HelloWorld.ui.xml
1 < ui:UiBinder xmlns:ui = ’ urn:ui:com . google . gwt . uibinder ’ >
2    < div >
3       Hello , < span ui:field = ’ nameSpan ’/ >.
4    </ div >
5 </ ui:UiBinder >


      HTML kann im UiBinder als nat¨rliches Element eingesetzt werden. Es k¨nnen alle
                                   u                                       o
    validen HTML-Elemente genutzt werden. Sollte man innerhalb der Programmlogik auf
    einzelne Elemente dieser Definitionen zugreifen m¨ssen, kann man mit Hilfe des ui:field
                                                    u
    Attributes einen eindeutigen Bezeichner festlegen. Innerhalb der Applikationslogik kann
    mit Hilfe von Java-Annotations auf diese Elemente zugegriffen werden:




                                              7
Listing 5: HelloWorld.java
1  // Could extend Widget instead
 2 public class HelloWorld extends UIObject {

 3   @UiTemplate ( " HelloWorld . ui . xml " )
 4   interface MyUiBinder extends UiBinder < DivElement , HelloWorld > {}
 5   private static MyUiBinder uiBinder = GWT . create ( MyUiBinder . class
        );
 6   @UiField SpanElement nameSpan ;
 7   public HelloWorld () {
 8     // createAndBindUi initializes this . nameSpan
 9     setElement ( uiBinder . createAndBindUi ( this ) ) ;
10   }
11   public void setName ( String name ) {
12     nameSpan . setInnerText ( name ) ;
13   }
14 }




                            Listing 6: HelloWorldWithCSS.ui.xml
1 < ui:UiBinder xmlns:ui = ’ urn:ui:com . google . gwt . uibinder ’ >
2    < ui:style >
3       . pretty { background - color: Skyblue ; }
4    </ ui:style >
5

6    < div class = ’{ style . pretty } ’ >
7       Hello , < span ui:field = ’ nameSpan ’/ >.
8    </ div >
9 </ ui:UiBinder >


      Um f¨r einzelne Elemente Style-Definitionen anzulegen, werden die Definitionen in-
          u
    nerhalb des <ui:style>-Tags erstellt und mit class=’style.STYLENAME’ dem Element
    hinzugef¨gt.
            u


    6. GWT-Objekte im UiBinder
    Neben HTMl- und CSS-Defintionen lassen sich in GWT UiBinder ebenfalls komplexe
    Anordnungen von GWT-Elementen modellieren. Hier gilt ebenfalls eine Konvention:
    Auf ein umschließendes Element wird die Metode add() mit dem enthaltenen Element
    aufgerufen. Dementsprechend verh¨lt sich die Modellierung innerhalb von UiBinder-
                                    a
    Definitionen genau so wie die Modellierung uber Objekte in Java. Allerdings lassen sich
                                              ¨



                                              8
diese XML-Definitionen bei weitem einfacher konstruieren und lesen als vergleichbare
    Java-Konstrukte.

                          Listing 7: UiBinderWithWidgets.ui.xml
1 < ui:UiBinder xmlns:ui = ’ urn:ui:com . google . gwt . uibinder ’
2       xmlns:g = ’ urn:import:com . google . gwt . user . client . ui ’ >
3    < g:H orizon talPan el >
4       < g:Label > This is a Label </ g:Label >
5    </ g:H orizon talPan el >
6 </ ui:UiBinder >


      Die Definitionen von von HTML- und GWT-Elementen lassen sich ebenfalls kombinie-
    ren. Hierbei wird dann anhand des verwendeten Namespaces zwischen den Elementtypen
    unterschieden.

                              Listing 8: UiBinderMixed.ui.xml
1  < g:D ockLa youtPa nel unit = ’ EM ’ >
2     < g:north size = ’5 ’ >
 3       < g:Label > Top </ g:Label >
 4    </ g:north >
 5    < g:center >
 6       < g:Label > Body </ g:Label >
 7    </ g:center >
 8    < g:west size = ’ 10 ’ >
 9       < g:HTML >
10          < ul >
11             < li > Sidebar </ li >
12          </ ul >
13       </ g:HTML >
14    </ g:west >
15 </ g:D ockLa youtPa nel >




                                            9
Teil III.
    JSNI
    7. Aufgaben
    In vielen F¨llen sind JavaScript-Funktionen bereits durch GWT-APIs gekapselt. Manch-
               a
    mal will man in seinem Projekt nun aber klassische JavaScript-Funktionen verwen-
    den, f¨r die es noch keine GWT-Schnittstelle gibt, oder hat das Bed¨rfnis auf bereits
          u                                                            u
    existierende JavaScript Bibliotheken zugreifen zu m¨ssen. F¨r diese beiden Anforde-
                                                       u       u
    rungen bietet GWT mit dem JavaScript Native Interface (JSNI)[Inca] eine Schnitt-
    stelle um Java-Methoden zu definieren, die nativen JavaScript-Code ausf¨hren. JSNI
                                                                          u
    wird genau zu diesem Zweck ebenfalls in der GWT-Klassenbibliothek verwendet um
    JavaScript-Funktionalit¨t zu kapseln. JSNI-Methoden werden beim Kompilieren vom
                           a
    GWT-Compiler in den restlichen JavaScript-Code eingef¨gt und ebenfalls durch den
                                                         u
    Compiler optimiert.
      JSNI-Methoden k¨nnen auf folgende Arten verwendet werden:
                     o

       • Implementieren von Java-Methoden direkt in JavaScript

       • Kapseln von JavaScript in in typsichere Java-Methoden

       • Aufrufen vom Java-Methoden aus JavaScript und umgekehrt

       • Werfen von Exceptions uber Java/JavaScript Grenzen hinweg
                               ¨

       • Lesen und schreiben von Java Membervariablen aus JavaScript

       • Verwenden des Entwicklermodus um sowohl Java als auch JavaScript Debuggen
         zu k¨nnen
             o

      JSNI-Code wird innerhalb von Java-Kommentaren definiert. Der Anfang der Methode
    wird durch die Zeichenkette “-” eingeleitet und durch “-” beendet. Die Schreibweise in
    Kommentaren ist notwendig, da sonst alle Java-Tools Syntaxfehler vermuten w¨rden, da
                                                                               u
    innerhalb des JavaScript-Blocks keine Datentypen vorhanden sind und auch abschließen-
    de Semikolons optional sind.

                                   Listing 9: JSNI Definition
1   public static native void alert ( String msg ) /* -{




                                              10
2     window . alert ( msg ) ;
3 } - */ ;




    8. Zugriff von Java auf JavaScript
    Da JSNI-Methoden eine Java-Signatur aufweisen, k¨nnen diese, wie “normale” Java-
                                                    o
    Methoden angesprochen und aufgerufen werden. Obwohl diese Methoden dynamisch
    typisierten JavaScript-Code enthalten, ist die Verwendung dieser Methoden statisch ty-
    pisiert und es werden vom Compiler alle ubergebenen Datentypen gepr¨ft.
                                            ¨                          u

                           Listing 10: Aufruf einer JSNI-Methode
1 public static void alert ( String msg ) {
2    alert ( " Hallo " ) ;
3 };




    9. Zugriff von JavaScript auf Java
    Ebenso wie es m¨glich ist von Java auf JSNI-Methoden zuzugreifen, ist es m¨glich von
                   o                                                          o
    JSNI-Methoden Membervariablen von Java-Objekten zu lesen und zu schreiben sowie
    Methoden von Java-Objekten aufzurufen.
      Allerdings muss beim Aufruf einer Java-Methode deren gesamter Paketpfad angegeben
                  ¨
    werden. Beim Ubergeben von Parametern muss zudem noch der Datentyp korrekt ange-
    geben werden. Dies ist notwendig um kompatibel zu statisch typisierten Java-Methoden
    zu bleiben. Die Angabe des Datentyps erfolgt in einem eigens in GWT verwendeten
    Format: “Ljava/lang/String;”. Java-Objekte werden mit einem “L” eingeleitet. Danach
    folgt ein voll qualifizierter Paketpfad f¨r den Datentyp und ein “;” zum Abschluss der
                                            u
    Sequenz. Primitive werden nur durch einzelne Buchstaben angegeben. I steht zum Bei-
    spiel f¨r Integer und F f¨r Float. Werden mehrere Parameter definiert, werden die dazu
           u                 u
    passenden Datentypen hinter einander ohne Trennzeichen aufgelistet.

                                 Listing 11: JSNIExample.java
1 public class JSNIExample {
2   String myInstanceField ;
3   static int myStaticField ;
4

5     void instanceFoo ( String s ) {
6       // use s




                                             11
7       }
 8       static void staticFoo ( String s ) {
 9         // use s
10       }
11

12       public native void bar ( JSNIExample x , String s ) /* -{
13           // Call instance method instanceFoo () on this
14           this . @com . google . gwt . examples . JSNIExample :: instanceFoo ( Ljava /
                  lang / String ;) ( s ) ;
15           // Call instance method instanceFoo () on x
16           x . @com . google . gwt . examples . JSNIExample :: instanceFoo ( Ljava / lang
                  / String ;) ( s ) ;
17           // Call static method staticFoo ()
18           @com . google . gwt . examples . JSNIExample :: staticFoo ( Ljava / lang /
                  String ;) ( s ) ;
19           // Read instance field on this
20           var val = this . @com . google . gwt . examples . JSNIExample ::
                  myInstanceField ;
21           // Write instance field on x
22           x . @com . google . gwt . examples . JSNIExample :: myInstanceField = val
                  + " and stuff ";
23           // Read static field ( no qualifier )
24           @com . google . gwt . examples . JSNIExample :: myStaticField = val + "
                  and stuff ";
25       } - */ ;
26   }



     10. JavaScriptObject
     Um JavaScript Objekte in die Java-Runtime ubergeben zu k¨nnen, kann der Daten-
                                                 ¨              o
     Typ JavaScripObject[Incg] verwendet werden. Diese Objekte lassen sich in einer Java-
     Variable speichern und wie eine solche behandeln. Wird dieses Objekt in eine JSNI-
     Methode ubergeben, kann es dort wie jedes andere JavaScript-Objekt behandelt werden.
             ¨
                                       ¨
                           Listing 12: Ubergabe von JavaScriptObject
 1 public static void test () {
 2    JavaScripObject window = getWindow () ;
 3 };

 4

 5   public static native JavaScripObject getWindow () /* -{



                                               12
6     return window ;
7 } - */ ;




                        13
Teil IV.
    Deferred Binding
    11. Aufgaben
    Ein großes Problem von JavaScript-Applikationen besteht darin, dass stellenweise große
    Unterschiede zwischen einzelnen JavaScript-Implementierungen in Browsern bestehen.
    Zum Einen bestehen zwischen mehreren Browsern Unterschiede zwischen vorhandenen
    APIs, was besonders unangenehm bei der DOM-API auff¨llt. Zum Anderen unterschei-
                                                      a
    den sich die Browser im Vorhandensein einzelner APIs und deren Features. Um diese
    Unterschiede auf einheitliche Java-Schnittstellen abbilden zu k¨nnen, wurde in GWT
                                                                   o
    Deferred Binding[Incc] eingef¨hrt.
                                 u
      Durch diesen Mechanismus ist es m¨glich bestimmte Java-Klassen beim Kompilieren
                                       o
    durch zuvor definierte Regeln auszutauschen. Dadurch kann man Unterschiede zwischen
    Browsern ausgleichen, indem bestimmte Klassen durch speziell auf einzelne Browser
    angepasste Implementierungen ausgetauscht werden. Durch diesen Mechanismus ist man
    somit nicht gezwungen innerhalb der Applikationslogik Unterschiede in Browsern zu
    behandeln sondern man kann die Unterscheidung dem Compiler uberlassen.
                                                               ¨


    12. Ersetzen f¨r einzelne Browser
                  u

                                Listing 13: PopupPanel.ui.xml
1   < module >
2      <! -- ... other configuration omitted ... -- >
3

4    <! -- IE has a completely different popup implementation -- >
5    < replace - with class = " com . google . gwt . user . client . ui . impl .
          PopupImplIE6 " >
6       < when - type - is class = " com . google . gwt . user . client . ui . impl .
            PopupImpl " / >
7       < when - property - is name = " user . agent " value = " ie6 " / >
8    </ replace - with >
9 </ module >


      In dieser Konfiguration wird beim Kompiliervorgang die Klasse “PopupImpl” durch
    “PopupImplIE6“’ ersetzt, wenn f¨r den Internet Explorer 6 kompiliert wird. Auf diese
                                   u



                                             14
Art und Weise kann die konkrete Implementierung einer Klasse anhand bestimmter
    Regeln ersetzt werden.

                                  Listing 14: PopupPanel.java
1 private static final PopupImpl impl = GWT . create ( PopupImpl . class ) ;
2 ...
3   public void setVisible ( boolean visible ) {
4     // ... common code for all implementations of PopupPanel ...
5

6         // If the PopupImpl creates an iframe shim , it ’s also
             necessary to hide it
7         // as well .
8         impl . setVisible ( getElement () , visible ) ;
9     }


                                Listing 15: PopupImplIE6.java
1     public native void setVisible ( Element popup , boolean visible ) /*
            -{
2         if ( popup . __frame ) {
3            popup . __frame . style . visibility = visible ? ’ visible ’ : ’
                hidden ’;
4         }
5     } - */ ;

      Mit der Anweisung “GWT.create()” l¨sst sich eine Instanz eines durch Deferred Bin-
                                        a
    ding definierten Objekts erstellen. Mit Hilfe einer Referenz auf diese Instanz lassen sich
    so Methodenaufrufe an die konkrete Implementierung delegieren. Dieser Aufbau kann
    im Allgemeinen mit dem Proxy Pattern[Wik] beschrieben werden.
    13. Ersetzen f¨r eigene Properties
                  u
    Neben dem Ersetzen von Klassen f¨r Konkrete Implementierungen einzelner Browser
                                    u
    lassen sich auch Klassen durch das Setzen eigener Properties austauschen:

                         Listing 16: Ersetzen mit Hilfe von Properties
1< module >
2 <! --   ... other configuration omitted ... -- >
3

4    <set - property name = " ownProperty " value = " false " / >
5




                                               15
6   < generate - with class = " com . google . gwt . user . rebind . rpc .
         ServiceInterfaceProxyGenerator ">
 7     < when - type - assignable class = " com . google . gwt . user . client . rpc .
           RemoteService " / >
 8     < when - property - is name = " ownProperty " value = " true " / >
 9 </ generate - with >

10 </ module >


      Mit Hilfe dieser Funktionalit¨t l¨sst sich das Austauschen von Klassen durch Konfi-
                                   a a
    gurationsoptionen steuern.




                                             16
Teil V.
    History Management
    14. Aufgaben
    AJAX1 Applikationen ¨ndern dynamisch Inhalte von Webseiten um deren Benutzung
                         a
    komfortabler zu machen. Diese Webseiten m¨ssen dadurch nicht mehr st¨ndig neu gela-
                                             u                          a
                                   ¨
    den werden. Durch dynamische Anderungen gehen allerdings zwei Kernfunktionen des
    Browsers als Plattform verloren: Die Benutzung der Browser-History und das Benutzen
    von persistenten Links, die auf einen bestimmten Teil der Webseite verweisen. Um die-
    se Funktionen in dynamischen GWT-Applikationen ebenfalls zur Verf¨gung zu haben,
                                                                     u
    wurde in im Google Webtoolkit eine Schnittstelle integriert, die es erlaubt die Browser-
    History zu manipulieren und auf Events zu reagieren[Incb]. Ein Beispiel f¨r solche Events
                                                                             u
    w¨re zum Beispiel das Klicken von Vor- bzw. Zur¨ck-Buttons.
     a                                             u


    15. History Tokens
    Um in GWT die History zu verwalten, wird an jede in der History navigierbare Seite
    ein Token generiert. Dieses Token kann vom Entwickler bestimmt werden und sollte
    m¨glichst einzigartig sein, da es einen definierten Zustand der Applikation widerspiegeln
     o
    sollte. Technisch gesehen, handelt es sich nur im einen String, der an die URL der
    Applikation angef¨gt wird. Dieser String hat normalerweise die Form “#tokenString”.
                     u

                                      Listing 17: History-Token
1   http: // www . example . com / com . example . gwt . HistoryExample /
       HistoryExample . html # page1

         Damit das History Management korrekt unterst¨tzt werden kann, muss in die HTML-
                                                     u
    Datei ein unsichtbares I-Frame mit der Id “ gwt historyFrame” eingef¨gt werden:
                                                                        u

                                    Listing 18: I-Frame in HTML
1    < iframe src = " javascript: ’ ’ "
2              id = " __g wt _h is to ry Fr am e "
3              style = " width:0 ; height:0 ; border:0 " > </ iframe >



     1
         Asynchronous JavaScript and XML




                                                 17
Um nun ein Event auszul¨sen, das den History-Status der Applikation ¨ndert, muss
                              o                                           a
    History.newItem() mit einem validen Token als Parameter aufgerufen werden:

                              Listing 19: History Manipulation
1          public void man ipula teHist ory ( Event event ) {
2            History . newItem ( " page " + event . getSelectedItem () ) ;
3          }



    16. History Handler
                                                                                ¨
    Wurde mit Hilfe von History.newItem() die History manipuliert, muss auf die Anderung
    reagiert und der Zustand der Anwendung anhand des erhaltenen Tokens ge¨ndert wer-
                                                                          a
    den. Hierzu bietet GWT die M¨glichkeit so genannte ValueChangeHandler f¨r History-
                                o                                          u
    Events zu definieren. Innerhalb dieses Handlers wird im Normalfall das Token geparst
    und der Zustand der Anwendung entsprechend ver¨ndert.
                                                  a

                              Listing 20: History Manipulation
1 History . a d d V a l u e C h a n g e H a n d l e r (
2     new ValueChangeHandler < String >() {
3       public void onValueChange ( ValueChangeEvent < String > event ) {
4           String historyToken = event . getValue () ;
5       // Parse the history token
6       // Change application state
7     }
8 }


      Sind die beiden Teile, also das Ausl¨sen von Events und das Reagieren auf diese,
                                          o
    implementiert, kann man Anwendungen mit URLs ausstatten, die einen Status wider-
    spiegeln. Wird bei solchen Anwendungen mittels Vor- bzw. Zur¨ck-Buttons navigiert
                                                                u
    oder uber Lesezeichen auf die Anwendung zugegriffen, ist der Entwickler in der Lage
         ¨
                  ¨
    anhand dieser Anderungen den Zustand der Applikation zu ¨ndern. Somit bietet ei-
                                                               a
    ne GWT-Applikation neben dynamischen Bedienelementen und schneller Reaktionszeit
    ebenfalls die M¨glichkeit uber gewohnte Mechanismen des Browsers zu navigieren.
                   o          ¨




                                            18
Teil VI.
Anhang
Literatur
[Inca] Google Inc. Coding basics - deferred binding. http://code.google.com/intl/
        de/webtoolkit/doc/latest/DevGuideCodingBasicsJSNI.html.

[Incb] Google Inc.     Coding basics - history.     http://code.google.com/intl/de/
        webtoolkit/doc/latest/DevGuideCodingBasicsHistory.html.

[Incc] Google   Inc.         Coding    basics   -   javascript   native   interface   (js-
        ni).             http://code.google.com/intl/de/webtoolkit/doc/latest/
        DevGuideCodingBasicsDeferred.html.

[Incd] Google Inc. Google wave: Powered by gwt. http://code.google.com/intl/de/
        events/io/2009/sessions/GoogleWavePoweredByGWT.html.

[Ince] Google Inc.       Google web toolkit.        http://code.google.com/intl/de/
        webtoolkit/.

[Incf] Google Inc.     Google web toolkit architecture: Best practices for architecting
        your gwt app. http://code.google.com/intl/de/events/io/2009/sessions/
        GoogleWebToolkitBestPractices.html.

[Incg] Google Inc.       Javascript object javadoc.      http://google-web-toolkit.
        googlecode.com/svn/javadoc/2.0/com/google/gwt/core/client/
        JavaScriptObject.html.

[ste]   cromwellian stefan.haustein, joelgwebber. Quake ii gwt port. http://code.
        google.com/p/quake2-gwt-port/.

[Wik] Wikipedia. Proxy pattern. http://en.wikipedia.org/wiki/Proxy_pattern.




                                           19

Contenu connexe

En vedette

. Nora graciela modolo
. Nora graciela modolo. Nora graciela modolo
. Nora graciela modoloPerlaSarubbi
 
eAqua und europeana4D - 2009
eAqua und europeana4D - 2009eAqua und europeana4D - 2009
eAqua und europeana4D - 2009Ralf Stockmann
 
Recetas para platos con hongos
Recetas para platos con hongosRecetas para platos con hongos
Recetas para platos con hongosPerlaSarubbi
 
Mantenimiento de pc
Mantenimiento de pcMantenimiento de pc
Mantenimiento de pcValeAngie
 
Estandar, competencia e indicadores de desempeño
Estandar, competencia e indicadores de desempeño Estandar, competencia e indicadores de desempeño
Estandar, competencia e indicadores de desempeño Camilasuarez199
 
Literatura, como creación artística.
Literatura, como creación artística.Literatura, como creación artística.
Literatura, como creación artística.Joselo8812
 
Master en Catàlisi Avançada i Modelització Molecular
Master en Catàlisi Avançada i Modelització MolecularMaster en Catàlisi Avançada i Modelització Molecular
Master en Catàlisi Avançada i Modelització Molecularpsalse
 

En vedette (20)

Caso eycos
Caso eycosCaso eycos
Caso eycos
 
Treatment
TreatmentTreatment
Treatment
 
. Nora graciela modolo
. Nora graciela modolo. Nora graciela modolo
. Nora graciela modolo
 
24jt
24jt24jt
24jt
 
eAqua und europeana4D - 2009
eAqua und europeana4D - 2009eAqua und europeana4D - 2009
eAqua und europeana4D - 2009
 
Cura y monja
Cura y monjaCura y monja
Cura y monja
 
Semana 36
Semana 36Semana 36
Semana 36
 
Presentacion sobre el aprendizaje
Presentacion sobre el aprendizajePresentacion sobre el aprendizaje
Presentacion sobre el aprendizaje
 
Beko BBL-Lizenzstatut 2013/2014
Beko BBL-Lizenzstatut 2013/2014Beko BBL-Lizenzstatut 2013/2014
Beko BBL-Lizenzstatut 2013/2014
 
Ensayo
 Ensayo  Ensayo
Ensayo
 
Recetas para platos con hongos
Recetas para platos con hongosRecetas para platos con hongos
Recetas para platos con hongos
 
Mantenimiento de pc
Mantenimiento de pcMantenimiento de pc
Mantenimiento de pc
 
Estandar, competencia e indicadores de desempeño
Estandar, competencia e indicadores de desempeño Estandar, competencia e indicadores de desempeño
Estandar, competencia e indicadores de desempeño
 
Literatura, como creación artística.
Literatura, como creación artística.Literatura, como creación artística.
Literatura, como creación artística.
 
Vidal berenice crm
Vidal berenice crmVidal berenice crm
Vidal berenice crm
 
Las drogas (1)
Las drogas (1)Las drogas (1)
Las drogas (1)
 
Gustavomonsalveppt. 3
Gustavomonsalveppt. 3Gustavomonsalveppt. 3
Gustavomonsalveppt. 3
 
Master en Catàlisi Avançada i Modelització Molecular
Master en Catàlisi Avançada i Modelització MolecularMaster en Catàlisi Avançada i Modelització Molecular
Master en Catàlisi Avançada i Modelització Molecular
 
Comercio electronico
Comercio electronicoComercio electronico
Comercio electronico
 
Gaindegia Micro-ficha Renta de Iparralde
Gaindegia Micro-ficha Renta de IparraldeGaindegia Micro-ficha Renta de Iparralde
Gaindegia Micro-ficha Renta de Iparralde
 

Similaire à GWT Introduction

Google Web Toolkit
Google Web ToolkitGoogle Web Toolkit
Google Web ToolkitTorben Brodt
 
Web-GUIs mit Vaadin
 Web-GUIs mit Vaadin Web-GUIs mit Vaadin
Web-GUIs mit Vaadingedoplan
 
PHP-Module in statischen Seiten - Architektur-Ansätze
PHP-Module in statischen Seiten - Architektur-AnsätzePHP-Module in statischen Seiten - Architektur-Ansätze
PHP-Module in statischen Seiten - Architektur-AnsätzeRalf Lütke
 
Java Magazin 5 / 2010 - Twitter nachgebaut mit Lift
Java Magazin 5 / 2010 - Twitter nachgebaut mit LiftJava Magazin 5 / 2010 - Twitter nachgebaut mit Lift
Java Magazin 5 / 2010 - Twitter nachgebaut mit LiftJohannes Hohenbichler
 
Durchgestartet? Eine Einführung in die Google App Engine / Java - Reloaded!
Durchgestartet? Eine Einführung in die Google App Engine / Java - Reloaded!Durchgestartet? Eine Einführung in die Google App Engine / Java - Reloaded!
Durchgestartet? Eine Einführung in die Google App Engine / Java - Reloaded!adesso AG
 
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...gedoplan
 
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...gedoplan
 
Gradle - Beginner's Workshop (german)
Gradle - Beginner's Workshop (german)Gradle - Beginner's Workshop (german)
Gradle - Beginner's Workshop (german)Joachim Baumann
 
Wie programmiere Ich ein Modul? Erste Schritte.
Wie programmiere Ich ein Modul? Erste Schritte.Wie programmiere Ich ein Modul? Erste Schritte.
Wie programmiere Ich ein Modul? Erste Schritte.flagbit
 
Automatischer Build mit Maven - OPITZ CONSULTING - Stefan Scheidt
Automatischer Build mit Maven - OPITZ CONSULTING - Stefan ScheidtAutomatischer Build mit Maven - OPITZ CONSULTING - Stefan Scheidt
Automatischer Build mit Maven - OPITZ CONSULTING - Stefan ScheidtOPITZ CONSULTING Deutschland
 
Java in the Cloud - am Beispiel der Google App Engineg
Java in the Cloud - am Beispiel der Google App EnginegJava in the Cloud - am Beispiel der Google App Engineg
Java in the Cloud - am Beispiel der Google App Engineggedoplan
 

Similaire à GWT Introduction (20)

GWT – Google Web Toolkit in der Praxis
GWT – Google Web Toolkit in der PraxisGWT – Google Web Toolkit in der Praxis
GWT – Google Web Toolkit in der Praxis
 
Elsholz stoll js_03_10
Elsholz stoll js_03_10Elsholz stoll js_03_10
Elsholz stoll js_03_10
 
Google Web Toolkit
Google Web ToolkitGoogle Web Toolkit
Google Web Toolkit
 
Web-GUIs mit Vaadin
 Web-GUIs mit Vaadin Web-GUIs mit Vaadin
Web-GUIs mit Vaadin
 
PHP-Module in statischen Seiten - Architektur-Ansätze
PHP-Module in statischen Seiten - Architektur-AnsätzePHP-Module in statischen Seiten - Architektur-Ansätze
PHP-Module in statischen Seiten - Architektur-Ansätze
 
GWT
GWTGWT
GWT
 
Java Magazin - Lift
Java Magazin - LiftJava Magazin - Lift
Java Magazin - Lift
 
Java Magazin 5 / 2010 - Twitter nachgebaut mit Lift
Java Magazin 5 / 2010 - Twitter nachgebaut mit LiftJava Magazin 5 / 2010 - Twitter nachgebaut mit Lift
Java Magazin 5 / 2010 - Twitter nachgebaut mit Lift
 
Durchgestartet? Eine Einführung in die Google App Engine / Java - Reloaded!
Durchgestartet? Eine Einführung in die Google App Engine / Java - Reloaded!Durchgestartet? Eine Einführung in die Google App Engine / Java - Reloaded!
Durchgestartet? Eine Einführung in die Google App Engine / Java - Reloaded!
 
MVVM mit WPF
MVVM mit WPFMVVM mit WPF
MVVM mit WPF
 
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...
 
Automatisierung mit grunt
Automatisierung mit gruntAutomatisierung mit grunt
Automatisierung mit grunt
 
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...
 
Gradle - Beginner's Workshop (german)
Gradle - Beginner's Workshop (german)Gradle - Beginner's Workshop (german)
Gradle - Beginner's Workshop (german)
 
Wie programmiere Ich ein Modul? Erste Schritte.
Wie programmiere Ich ein Modul? Erste Schritte.Wie programmiere Ich ein Modul? Erste Schritte.
Wie programmiere Ich ein Modul? Erste Schritte.
 
Automatischer Build mit Maven - OPITZ CONSULTING - Stefan Scheidt
Automatischer Build mit Maven - OPITZ CONSULTING - Stefan ScheidtAutomatischer Build mit Maven - OPITZ CONSULTING - Stefan Scheidt
Automatischer Build mit Maven - OPITZ CONSULTING - Stefan Scheidt
 
react-de.pdf
react-de.pdfreact-de.pdf
react-de.pdf
 
Wicket Kurzübersicht
Wicket KurzübersichtWicket Kurzübersicht
Wicket Kurzübersicht
 
Einsteiger Workshop
Einsteiger WorkshopEinsteiger Workshop
Einsteiger Workshop
 
Java in the Cloud - am Beispiel der Google App Engineg
Java in the Cloud - am Beispiel der Google App EnginegJava in the Cloud - am Beispiel der Google App Engineg
Java in the Cloud - am Beispiel der Google App Engineg
 

Plus de pfleidi

The VP8 Video Codec
The VP8 Video CodecThe VP8 Video Codec
The VP8 Video Codecpfleidi
 
Scale The Realtime Web
Scale The Realtime WebScale The Realtime Web
Scale The Realtime Webpfleidi
 
Scala - A Scalable Language
Scala - A Scalable LanguageScala - A Scalable Language
Scala - A Scalable Languagepfleidi
 
YAXIM - Yet Another XMPP Instant Messenger
YAXIM - Yet Another XMPP Instant MessengerYAXIM - Yet Another XMPP Instant Messenger
YAXIM - Yet Another XMPP Instant Messengerpfleidi
 
Designpatterns in Ruby
Designpatterns in RubyDesignpatterns in Ruby
Designpatterns in Rubypfleidi
 

Plus de pfleidi (6)

The VP8 Video Codec
The VP8 Video CodecThe VP8 Video Codec
The VP8 Video Codec
 
Scale The Realtime Web
Scale The Realtime WebScale The Realtime Web
Scale The Realtime Web
 
Scala - A Scalable Language
Scala - A Scalable LanguageScala - A Scalable Language
Scala - A Scalable Language
 
YAXIM - Yet Another XMPP Instant Messenger
YAXIM - Yet Another XMPP Instant MessengerYAXIM - Yet Another XMPP Instant Messenger
YAXIM - Yet Another XMPP Instant Messenger
 
OpenWRT
OpenWRTOpenWRT
OpenWRT
 
Designpatterns in Ruby
Designpatterns in RubyDesignpatterns in Ruby
Designpatterns in Ruby
 

GWT Introduction

  • 1. Hochschule der Medien Stuttgart, Studiengang Medieninformatik Das Google Webtoolkit von Sven Pfleiderer http://blog.roothausen.de sven@roothausen.de 13. Januar 2011
  • 2. Inhaltsverzeichnis I. Das Google Webtoolkit 4 1. Was ist GWT? 4 2. Einsatzgebiete 4 3. Applikationsstruktur 4 II. UiBinder 7 4. Aufgaben 7 5. HTML und CSS im UiBinder 7 6. GWT-Objekte im UiBinder 8 III. JSNI 10 7. Aufgaben 10 8. Zugriff von Java auf JavaScript 11 9. Zugriff von JavaScript auf Java 11 10.JavaScriptObject 12 IV. Deferred Binding 14 11.Aufgaben 14 12.Ersetzen f¨r einzelne Browser u 14 13.Ersetzen f¨r eigene Properties u 15 2
  • 3. V. History Management 17 14.Aufgaben 17 15.History Tokens 17 16.History Handler 18 VI. Anhang 19 3
  • 4. Teil I. Das Google Webtoolkit 1. Was ist GWT? Das Google Webtoolkit[Ince] ist ein von Google entwickeltes Anwendungsframework zum Erstellen von komplexen, sehr dynamischen Webanwendungen. Bei diesen Anwendun- gen handelt es sich um Software, die direkt im Client, also im Webbrowser, ausgef¨hrt u wird. Diese Software kann hierbei komplett in Java entwickelt werden und wird von GWT in, f¨r das Web typische, Formate wie HTML, JavaScript und CSS kompiliert. u Grafische Elemente k¨nnen, ¨hnlich wie in anderen Java UI-Toolkits wie zum Beispiel o a Swing oder AWT, komplett objektorientiert aufgebaut und verwendet werden. GWT- Applikationen lassen sich zudem einfach in statische Webseiten oder bereits vorhandene Webapplikationen integrieren. GWT enth¨lt zudem noch Werkzeuge, die die Entwicklungsarbeit stark vereinfachen. a Darunter sind unter anderem Scripte um ein Grundger¨st einer Applikation zu erstellen u oder Plugins, die es erlauben Anwendungen “live” in einem Browser zu debuggen. 2. Einsatzgebiete GWT kommt vor allem dort zum Einsatz, wo Webanwendungen m¨glichst dynamisch o und benutzerfreundlich sein sollen. Also an Stellen, an denen man von einer Webapplika- tion erwartet, dass sie sich wie eine ¨quivalente Desktop-Applikation verh¨lt. Ziel ist es a a den Benutzer so wenig wie m¨glich durch Neuladen der Webseite aufzuhalten und einen o m¨glichst hohen Komfort in der Benutzung zu bieten. Es gibt mittlerweile sogar Projek- o te, die GWT als Plattform f¨r webbasierte 3D-Spiele verwenden[ste]. Bei Google kommt u GWT vor allem bei Google Wave[Incd] und dem Google Adwords Control Panel[Incf] zum Einsatz. 3. Applikationsstruktur Eine GWT-Applikation besteht aus mindestens drei Komponenten: Einer HTML-Datei, einer GWT.XML-Datei und einer Java Klasse. Diese Komponenten werden normalerwei- se schon beim Erstellen eines neuen Projektes generiert und m¨ssen nur noch angepasst u und erweitert werden. 4
  • 5. Listing 1: Index.html 1 <! doctype html > 2 < html > 3 < head > 4 ... 5 < title > Hello GWT </ title > 6 < script type = " text / javascript " 7 language = " javascript " 8 src = " gwttest / gwttest . nocache . js " > 9 </ script > 10 </ head > 11 < body > 12 < h1 > Hello GWT ! </ h1 > 13 < div id = " appcontainer " / > 14 </ body > 15 </ html > In in der HTML-Datei wird vor allem der JavaScript-Code eingebunden, der sp¨ter, a je nach Browser, den entsprechenden Applikationscode einbindet. Die Aufgabe von *.no- cach.js Dateien besteht ausschließlich darin, den Browsertyp zu erkennen und anhand dieses Typs die entsprechenden *.cache.js-Dateien mit der konkreten Applikationslo- gik zu laden. Zudem wird in diesem Beispiel ein DIV-Element definiert. Dieses wird, wie sp¨ter beschrieben, GWT UI-Elemente aufnehmen. Durch die M¨glichkeit einzelne a o DIV-Elemente als Container f¨r GWT-Elemente zu verwenden, ist man in der Lage sta- u tische Webseiten zu erstellen und diese durch einbinden von GWT mit Zusatzfunktionen auszustatten. Listing 2: GWTTest.gwt.xml enth¨lt die Konfiguration des GWT Moduls a 1 <? xml version = " 1.0 " encoding = " UTF -8 " ? > 2 < module rename - to = ’ gwttest ’ > 3 <! -- Inherit the core Web Toolkit stuff . -- > 4 < inherits name = ’ com . google . gwt . user . User ’/ > 5 6 <! -- Inherit the default GWT style sheet . -- > 7 < inherits name = ’ com . google . gwt . user . theme . standard . Standard ’/ > 8 9 <! -- Specify the app entry point class . -- > 10 < entry - point class = ’ de . roothausen . gwt . test . client . GWTTest ’/ > 11 12 <! -- Specify the paths for translatable code -- > 5
  • 6. 13 < source path = ’ client ’/ > 14 </ module > In den *.gwt.xml-Dateien werden mittels der inherits-Anweisung weitere GWT-Module geladen. Zudem wird die Java-Klasse bestimmt, die als Einstiegspunkt der Programm- logik dient. Werden weitere verwendete Java-Klassen in zus¨tzlichen Ordnern ben¨tigt, a o k¨nnen Pfade definiert werden um diese zus¨tzlich einzubinden. In *.gwt.xml-Dateien o a besteht zudem die M¨glichkeit Themes und Stylesheets zu definieren und einzubinden. o Des Weiteren werden in diesen Konfigurationsdateien, wie in Teil IV beschrieben, die Definition von Deferred Binding vorgenommen. Listing 3: GWTTest stellt den Einstiegspunkt der Applikation dar 1 public class GWTTest implements EntryPoint { 2 3 public void onModuleLoad () { 4 VerticalPanel container = new VerticalPanel () ; 5 final Label helloLabel = new Label ( " Hello " ) ; 6 Button helloButton = new Button ( " Change Text " ) ; 7 container . add ( helloLabel ) ; 8 container . add ( helloButton ) ; 9 10 helloButton . addClickHandler ( new ClickHandler () { 11 @Override 12 public void onClick ( ClickEvent event ) { 13 helloLabel . setText ( " Button clicked " ) ; 14 } 15 }) ; 16 RootPanel . get ( " appcontainer " ) . add ( container ) ; 17 } 18 } Die eigentliche Programmlogik wird, wie bereits beschrieben, in Java definiert. Ver- ticalPanel, Label und Button sind hier GUI-Elemente aus dem GWT-SDK. Diese Ele- mente k¨nnen, wie in anderen Toolkits auch, miteinander kombiniert und anhand ihrer o Vererbungshierarchie verschachtelt werden: Das erstellte Panel nimmt das Label und den Button auf und wird vom GWT-Framework in das zuvor definierte DIV-Element eingef¨gt. u 6
  • 7. Teil II. UiBinder 4. Aufgaben Grundlegend bestehen GUI-Elemente von GWT-Applikationen ausschließlich aus HTML und CSS. Daher ist es nur nat¨rlich, feste und unver¨nderliche Bereiche der Webappli- u a kation auf genau dieser Abstraktionsebene definieren zu k¨nnen. Zudem ist es es sinnvoll o dynamische GUI-Elemente in einer deklarativen Sprache zu definieren ohne diese uber ¨ Programmcode einzeln zusammen bauen zu m¨ssen. Diese Aufgaben werden durch das u UiBinder Framework abgebildet. 5. HTML und CSS im UiBinder Der einfachste Anwendungsfall des UiBinders besteht darin, fixen HTML- und CSS- Code zu definieren, der neben dynamischen Inhalten in Anwendungen eigebaut werden kann. UiBinder Definitionen werden mit der Dateiendung .ui.xml abgespeichert. Norma- lerweise wird die passende UiBinder-Definition f¨r eine bestimmte Java-Klasse uber eine u ¨ Namenskonvention festgelegt. Im Falle der Klasse “HelloWorld.java” w¨rde automatisch u die UiBinder-Datei “HelloWorld.ui.xml” verwendet werden. Sollten sich die Namen der Java-Klasse und der UiBinder-Definition unterscheiden, kann innerhalb der Klasse mit Hilfe der @UiTemplate-Annotation explizit auf eine *.ui.xml-Datei verwiesen werden. Listing 4: HelloWorld.ui.xml 1 < ui:UiBinder xmlns:ui = ’ urn:ui:com . google . gwt . uibinder ’ > 2 < div > 3 Hello , < span ui:field = ’ nameSpan ’/ >. 4 </ div > 5 </ ui:UiBinder > HTML kann im UiBinder als nat¨rliches Element eingesetzt werden. Es k¨nnen alle u o validen HTML-Elemente genutzt werden. Sollte man innerhalb der Programmlogik auf einzelne Elemente dieser Definitionen zugreifen m¨ssen, kann man mit Hilfe des ui:field u Attributes einen eindeutigen Bezeichner festlegen. Innerhalb der Applikationslogik kann mit Hilfe von Java-Annotations auf diese Elemente zugegriffen werden: 7
  • 8. Listing 5: HelloWorld.java 1 // Could extend Widget instead 2 public class HelloWorld extends UIObject { 3 @UiTemplate ( " HelloWorld . ui . xml " ) 4 interface MyUiBinder extends UiBinder < DivElement , HelloWorld > {} 5 private static MyUiBinder uiBinder = GWT . create ( MyUiBinder . class ); 6 @UiField SpanElement nameSpan ; 7 public HelloWorld () { 8 // createAndBindUi initializes this . nameSpan 9 setElement ( uiBinder . createAndBindUi ( this ) ) ; 10 } 11 public void setName ( String name ) { 12 nameSpan . setInnerText ( name ) ; 13 } 14 } Listing 6: HelloWorldWithCSS.ui.xml 1 < ui:UiBinder xmlns:ui = ’ urn:ui:com . google . gwt . uibinder ’ > 2 < ui:style > 3 . pretty { background - color: Skyblue ; } 4 </ ui:style > 5 6 < div class = ’{ style . pretty } ’ > 7 Hello , < span ui:field = ’ nameSpan ’/ >. 8 </ div > 9 </ ui:UiBinder > Um f¨r einzelne Elemente Style-Definitionen anzulegen, werden die Definitionen in- u nerhalb des <ui:style>-Tags erstellt und mit class=’style.STYLENAME’ dem Element hinzugef¨gt. u 6. GWT-Objekte im UiBinder Neben HTMl- und CSS-Defintionen lassen sich in GWT UiBinder ebenfalls komplexe Anordnungen von GWT-Elementen modellieren. Hier gilt ebenfalls eine Konvention: Auf ein umschließendes Element wird die Metode add() mit dem enthaltenen Element aufgerufen. Dementsprechend verh¨lt sich die Modellierung innerhalb von UiBinder- a Definitionen genau so wie die Modellierung uber Objekte in Java. Allerdings lassen sich ¨ 8
  • 9. diese XML-Definitionen bei weitem einfacher konstruieren und lesen als vergleichbare Java-Konstrukte. Listing 7: UiBinderWithWidgets.ui.xml 1 < ui:UiBinder xmlns:ui = ’ urn:ui:com . google . gwt . uibinder ’ 2 xmlns:g = ’ urn:import:com . google . gwt . user . client . ui ’ > 3 < g:H orizon talPan el > 4 < g:Label > This is a Label </ g:Label > 5 </ g:H orizon talPan el > 6 </ ui:UiBinder > Die Definitionen von von HTML- und GWT-Elementen lassen sich ebenfalls kombinie- ren. Hierbei wird dann anhand des verwendeten Namespaces zwischen den Elementtypen unterschieden. Listing 8: UiBinderMixed.ui.xml 1 < g:D ockLa youtPa nel unit = ’ EM ’ > 2 < g:north size = ’5 ’ > 3 < g:Label > Top </ g:Label > 4 </ g:north > 5 < g:center > 6 < g:Label > Body </ g:Label > 7 </ g:center > 8 < g:west size = ’ 10 ’ > 9 < g:HTML > 10 < ul > 11 < li > Sidebar </ li > 12 </ ul > 13 </ g:HTML > 14 </ g:west > 15 </ g:D ockLa youtPa nel > 9
  • 10. Teil III. JSNI 7. Aufgaben In vielen F¨llen sind JavaScript-Funktionen bereits durch GWT-APIs gekapselt. Manch- a mal will man in seinem Projekt nun aber klassische JavaScript-Funktionen verwen- den, f¨r die es noch keine GWT-Schnittstelle gibt, oder hat das Bed¨rfnis auf bereits u u existierende JavaScript Bibliotheken zugreifen zu m¨ssen. F¨r diese beiden Anforde- u u rungen bietet GWT mit dem JavaScript Native Interface (JSNI)[Inca] eine Schnitt- stelle um Java-Methoden zu definieren, die nativen JavaScript-Code ausf¨hren. JSNI u wird genau zu diesem Zweck ebenfalls in der GWT-Klassenbibliothek verwendet um JavaScript-Funktionalit¨t zu kapseln. JSNI-Methoden werden beim Kompilieren vom a GWT-Compiler in den restlichen JavaScript-Code eingef¨gt und ebenfalls durch den u Compiler optimiert. JSNI-Methoden k¨nnen auf folgende Arten verwendet werden: o • Implementieren von Java-Methoden direkt in JavaScript • Kapseln von JavaScript in in typsichere Java-Methoden • Aufrufen vom Java-Methoden aus JavaScript und umgekehrt • Werfen von Exceptions uber Java/JavaScript Grenzen hinweg ¨ • Lesen und schreiben von Java Membervariablen aus JavaScript • Verwenden des Entwicklermodus um sowohl Java als auch JavaScript Debuggen zu k¨nnen o JSNI-Code wird innerhalb von Java-Kommentaren definiert. Der Anfang der Methode wird durch die Zeichenkette “-” eingeleitet und durch “-” beendet. Die Schreibweise in Kommentaren ist notwendig, da sonst alle Java-Tools Syntaxfehler vermuten w¨rden, da u innerhalb des JavaScript-Blocks keine Datentypen vorhanden sind und auch abschließen- de Semikolons optional sind. Listing 9: JSNI Definition 1 public static native void alert ( String msg ) /* -{ 10
  • 11. 2 window . alert ( msg ) ; 3 } - */ ; 8. Zugriff von Java auf JavaScript Da JSNI-Methoden eine Java-Signatur aufweisen, k¨nnen diese, wie “normale” Java- o Methoden angesprochen und aufgerufen werden. Obwohl diese Methoden dynamisch typisierten JavaScript-Code enthalten, ist die Verwendung dieser Methoden statisch ty- pisiert und es werden vom Compiler alle ubergebenen Datentypen gepr¨ft. ¨ u Listing 10: Aufruf einer JSNI-Methode 1 public static void alert ( String msg ) { 2 alert ( " Hallo " ) ; 3 }; 9. Zugriff von JavaScript auf Java Ebenso wie es m¨glich ist von Java auf JSNI-Methoden zuzugreifen, ist es m¨glich von o o JSNI-Methoden Membervariablen von Java-Objekten zu lesen und zu schreiben sowie Methoden von Java-Objekten aufzurufen. Allerdings muss beim Aufruf einer Java-Methode deren gesamter Paketpfad angegeben ¨ werden. Beim Ubergeben von Parametern muss zudem noch der Datentyp korrekt ange- geben werden. Dies ist notwendig um kompatibel zu statisch typisierten Java-Methoden zu bleiben. Die Angabe des Datentyps erfolgt in einem eigens in GWT verwendeten Format: “Ljava/lang/String;”. Java-Objekte werden mit einem “L” eingeleitet. Danach folgt ein voll qualifizierter Paketpfad f¨r den Datentyp und ein “;” zum Abschluss der u Sequenz. Primitive werden nur durch einzelne Buchstaben angegeben. I steht zum Bei- spiel f¨r Integer und F f¨r Float. Werden mehrere Parameter definiert, werden die dazu u u passenden Datentypen hinter einander ohne Trennzeichen aufgelistet. Listing 11: JSNIExample.java 1 public class JSNIExample { 2 String myInstanceField ; 3 static int myStaticField ; 4 5 void instanceFoo ( String s ) { 6 // use s 11
  • 12. 7 } 8 static void staticFoo ( String s ) { 9 // use s 10 } 11 12 public native void bar ( JSNIExample x , String s ) /* -{ 13 // Call instance method instanceFoo () on this 14 this . @com . google . gwt . examples . JSNIExample :: instanceFoo ( Ljava / lang / String ;) ( s ) ; 15 // Call instance method instanceFoo () on x 16 x . @com . google . gwt . examples . JSNIExample :: instanceFoo ( Ljava / lang / String ;) ( s ) ; 17 // Call static method staticFoo () 18 @com . google . gwt . examples . JSNIExample :: staticFoo ( Ljava / lang / String ;) ( s ) ; 19 // Read instance field on this 20 var val = this . @com . google . gwt . examples . JSNIExample :: myInstanceField ; 21 // Write instance field on x 22 x . @com . google . gwt . examples . JSNIExample :: myInstanceField = val + " and stuff "; 23 // Read static field ( no qualifier ) 24 @com . google . gwt . examples . JSNIExample :: myStaticField = val + " and stuff "; 25 } - */ ; 26 } 10. JavaScriptObject Um JavaScript Objekte in die Java-Runtime ubergeben zu k¨nnen, kann der Daten- ¨ o Typ JavaScripObject[Incg] verwendet werden. Diese Objekte lassen sich in einer Java- Variable speichern und wie eine solche behandeln. Wird dieses Objekt in eine JSNI- Methode ubergeben, kann es dort wie jedes andere JavaScript-Objekt behandelt werden. ¨ ¨ Listing 12: Ubergabe von JavaScriptObject 1 public static void test () { 2 JavaScripObject window = getWindow () ; 3 }; 4 5 public static native JavaScripObject getWindow () /* -{ 12
  • 13. 6 return window ; 7 } - */ ; 13
  • 14. Teil IV. Deferred Binding 11. Aufgaben Ein großes Problem von JavaScript-Applikationen besteht darin, dass stellenweise große Unterschiede zwischen einzelnen JavaScript-Implementierungen in Browsern bestehen. Zum Einen bestehen zwischen mehreren Browsern Unterschiede zwischen vorhandenen APIs, was besonders unangenehm bei der DOM-API auff¨llt. Zum Anderen unterschei- a den sich die Browser im Vorhandensein einzelner APIs und deren Features. Um diese Unterschiede auf einheitliche Java-Schnittstellen abbilden zu k¨nnen, wurde in GWT o Deferred Binding[Incc] eingef¨hrt. u Durch diesen Mechanismus ist es m¨glich bestimmte Java-Klassen beim Kompilieren o durch zuvor definierte Regeln auszutauschen. Dadurch kann man Unterschiede zwischen Browsern ausgleichen, indem bestimmte Klassen durch speziell auf einzelne Browser angepasste Implementierungen ausgetauscht werden. Durch diesen Mechanismus ist man somit nicht gezwungen innerhalb der Applikationslogik Unterschiede in Browsern zu behandeln sondern man kann die Unterscheidung dem Compiler uberlassen. ¨ 12. Ersetzen f¨r einzelne Browser u Listing 13: PopupPanel.ui.xml 1 < module > 2 <! -- ... other configuration omitted ... -- > 3 4 <! -- IE has a completely different popup implementation -- > 5 < replace - with class = " com . google . gwt . user . client . ui . impl . PopupImplIE6 " > 6 < when - type - is class = " com . google . gwt . user . client . ui . impl . PopupImpl " / > 7 < when - property - is name = " user . agent " value = " ie6 " / > 8 </ replace - with > 9 </ module > In dieser Konfiguration wird beim Kompiliervorgang die Klasse “PopupImpl” durch “PopupImplIE6“’ ersetzt, wenn f¨r den Internet Explorer 6 kompiliert wird. Auf diese u 14
  • 15. Art und Weise kann die konkrete Implementierung einer Klasse anhand bestimmter Regeln ersetzt werden. Listing 14: PopupPanel.java 1 private static final PopupImpl impl = GWT . create ( PopupImpl . class ) ; 2 ... 3 public void setVisible ( boolean visible ) { 4 // ... common code for all implementations of PopupPanel ... 5 6 // If the PopupImpl creates an iframe shim , it ’s also necessary to hide it 7 // as well . 8 impl . setVisible ( getElement () , visible ) ; 9 } Listing 15: PopupImplIE6.java 1 public native void setVisible ( Element popup , boolean visible ) /* -{ 2 if ( popup . __frame ) { 3 popup . __frame . style . visibility = visible ? ’ visible ’ : ’ hidden ’; 4 } 5 } - */ ; Mit der Anweisung “GWT.create()” l¨sst sich eine Instanz eines durch Deferred Bin- a ding definierten Objekts erstellen. Mit Hilfe einer Referenz auf diese Instanz lassen sich so Methodenaufrufe an die konkrete Implementierung delegieren. Dieser Aufbau kann im Allgemeinen mit dem Proxy Pattern[Wik] beschrieben werden. 13. Ersetzen f¨r eigene Properties u Neben dem Ersetzen von Klassen f¨r Konkrete Implementierungen einzelner Browser u lassen sich auch Klassen durch das Setzen eigener Properties austauschen: Listing 16: Ersetzen mit Hilfe von Properties 1< module > 2 <! -- ... other configuration omitted ... -- > 3 4 <set - property name = " ownProperty " value = " false " / > 5 15
  • 16. 6 < generate - with class = " com . google . gwt . user . rebind . rpc . ServiceInterfaceProxyGenerator "> 7 < when - type - assignable class = " com . google . gwt . user . client . rpc . RemoteService " / > 8 < when - property - is name = " ownProperty " value = " true " / > 9 </ generate - with > 10 </ module > Mit Hilfe dieser Funktionalit¨t l¨sst sich das Austauschen von Klassen durch Konfi- a a gurationsoptionen steuern. 16
  • 17. Teil V. History Management 14. Aufgaben AJAX1 Applikationen ¨ndern dynamisch Inhalte von Webseiten um deren Benutzung a komfortabler zu machen. Diese Webseiten m¨ssen dadurch nicht mehr st¨ndig neu gela- u a ¨ den werden. Durch dynamische Anderungen gehen allerdings zwei Kernfunktionen des Browsers als Plattform verloren: Die Benutzung der Browser-History und das Benutzen von persistenten Links, die auf einen bestimmten Teil der Webseite verweisen. Um die- se Funktionen in dynamischen GWT-Applikationen ebenfalls zur Verf¨gung zu haben, u wurde in im Google Webtoolkit eine Schnittstelle integriert, die es erlaubt die Browser- History zu manipulieren und auf Events zu reagieren[Incb]. Ein Beispiel f¨r solche Events u w¨re zum Beispiel das Klicken von Vor- bzw. Zur¨ck-Buttons. a u 15. History Tokens Um in GWT die History zu verwalten, wird an jede in der History navigierbare Seite ein Token generiert. Dieses Token kann vom Entwickler bestimmt werden und sollte m¨glichst einzigartig sein, da es einen definierten Zustand der Applikation widerspiegeln o sollte. Technisch gesehen, handelt es sich nur im einen String, der an die URL der Applikation angef¨gt wird. Dieser String hat normalerweise die Form “#tokenString”. u Listing 17: History-Token 1 http: // www . example . com / com . example . gwt . HistoryExample / HistoryExample . html # page1 Damit das History Management korrekt unterst¨tzt werden kann, muss in die HTML- u Datei ein unsichtbares I-Frame mit der Id “ gwt historyFrame” eingef¨gt werden: u Listing 18: I-Frame in HTML 1 < iframe src = " javascript: ’ ’ " 2 id = " __g wt _h is to ry Fr am e " 3 style = " width:0 ; height:0 ; border:0 " > </ iframe > 1 Asynchronous JavaScript and XML 17
  • 18. Um nun ein Event auszul¨sen, das den History-Status der Applikation ¨ndert, muss o a History.newItem() mit einem validen Token als Parameter aufgerufen werden: Listing 19: History Manipulation 1 public void man ipula teHist ory ( Event event ) { 2 History . newItem ( " page " + event . getSelectedItem () ) ; 3 } 16. History Handler ¨ Wurde mit Hilfe von History.newItem() die History manipuliert, muss auf die Anderung reagiert und der Zustand der Anwendung anhand des erhaltenen Tokens ge¨ndert wer- a den. Hierzu bietet GWT die M¨glichkeit so genannte ValueChangeHandler f¨r History- o u Events zu definieren. Innerhalb dieses Handlers wird im Normalfall das Token geparst und der Zustand der Anwendung entsprechend ver¨ndert. a Listing 20: History Manipulation 1 History . a d d V a l u e C h a n g e H a n d l e r ( 2 new ValueChangeHandler < String >() { 3 public void onValueChange ( ValueChangeEvent < String > event ) { 4 String historyToken = event . getValue () ; 5 // Parse the history token 6 // Change application state 7 } 8 } Sind die beiden Teile, also das Ausl¨sen von Events und das Reagieren auf diese, o implementiert, kann man Anwendungen mit URLs ausstatten, die einen Status wider- spiegeln. Wird bei solchen Anwendungen mittels Vor- bzw. Zur¨ck-Buttons navigiert u oder uber Lesezeichen auf die Anwendung zugegriffen, ist der Entwickler in der Lage ¨ ¨ anhand dieser Anderungen den Zustand der Applikation zu ¨ndern. Somit bietet ei- a ne GWT-Applikation neben dynamischen Bedienelementen und schneller Reaktionszeit ebenfalls die M¨glichkeit uber gewohnte Mechanismen des Browsers zu navigieren. o ¨ 18
  • 19. Teil VI. Anhang Literatur [Inca] Google Inc. Coding basics - deferred binding. http://code.google.com/intl/ de/webtoolkit/doc/latest/DevGuideCodingBasicsJSNI.html. [Incb] Google Inc. Coding basics - history. http://code.google.com/intl/de/ webtoolkit/doc/latest/DevGuideCodingBasicsHistory.html. [Incc] Google Inc. Coding basics - javascript native interface (js- ni). http://code.google.com/intl/de/webtoolkit/doc/latest/ DevGuideCodingBasicsDeferred.html. [Incd] Google Inc. Google wave: Powered by gwt. http://code.google.com/intl/de/ events/io/2009/sessions/GoogleWavePoweredByGWT.html. [Ince] Google Inc. Google web toolkit. http://code.google.com/intl/de/ webtoolkit/. [Incf] Google Inc. Google web toolkit architecture: Best practices for architecting your gwt app. http://code.google.com/intl/de/events/io/2009/sessions/ GoogleWebToolkitBestPractices.html. [Incg] Google Inc. Javascript object javadoc. http://google-web-toolkit. googlecode.com/svn/javadoc/2.0/com/google/gwt/core/client/ JavaScriptObject.html. [ste] cromwellian stefan.haustein, joelgwebber. Quake ii gwt port. http://code. google.com/p/quake2-gwt-port/. [Wik] Wikipedia. Proxy pattern. http://en.wikipedia.org/wiki/Proxy_pattern. 19