Skip to main content
RJUG : 12-Mar-2012                                                                                 © Copyright 2013, Software Alchemy




                                  The Google Web Toolkit
                                                                Getting
                                                                started

                                    Using                                                 Building
                                  Data Grids                                               Views



                                                              Google
                                                             Web Toolkit


                                  Extending                                              Building
                                    GWT                                                 Presenters

                                                              Talking to
                                                              the Server



                                                             Bryan Basham
                                                            Software Alchemy
                                                          basham47@gmail.com
                                               http://www.linkedin.com/in/SoftwareAlchemist

Bryan Basham – The Google Web Toolkit                                                                                           Slide 1
RJUG : 12-Mar-2012                                                                                         © Copyright 2013, Software Alchemy




                                  Getting Started...
                                                               View
                                                                      Presenter
                                                      Model                         Like Java RMI
                                                                MVP                    ...but asynchronous
                                                                              RPC
                                               Single-Page
                                               Model
                                                                                  Config
                                                                Getting
                                                                started
                                                DEMO #1

                                    Using                                                     Building
                                  Data Grids                                                   Views



                                                               Google
                                                              Web Toolkit


                                  Extending                                                  Building
                                    GWT                                                     Presenters

                                                               Talking to
                                                               the Server




Bryan Basham – The Google Web Toolkit                                                                                                   Slide 2
RJUG : 12-Mar-2012                                          © Copyright 2013, Software Alchemy




                                  GWT Basics

      ●     Single-Page Web Applications
      ●     Rich-client: phat without being fat
      ●     GUI code built in Java but translated into
            JavaScript at build-time
                    –    Java classes represent HTML elements and
                           widgets
                    –    Rich client-side domain model using Java
                          POJOs
      ●     Client/server communication via OO-based
            RPC; a lot like Java's RMI
Bryan Basham – The Google Web Toolkit                                                    Slide 3
RJUG : 12-Mar-2012                                    © Copyright 2013, Software Alchemy




                                  Demo: “Hello World”




Bryan Basham – The Google Web Toolkit                                              Slide 4
RJUG : 12-Mar-2012                                                   © Copyright 2013, Software Alchemy




                                  Typical GWT Architecture


                                 Desktop      Internet    Server                  Database
          User

                                ...........
                                ...........
                                ...........


                               Client-side               Server-side
                              Components                 Components
                                & DTOs                    & Entities




Bryan Basham – The Google Web Toolkit                                                             Slide 5
RJUG : 12-Mar-2012                                                                                                                 © Copyright 2013, Software Alchemy




                                           Typical GWT Architecture


                                          Desktop                                          Internet                   Server                    Database
          User

                                          ...........
                                          ...........
                                          ...........
             use
           gen

                 r ac
              e    rate

                     tion
                        sH




                                                                       GWT's serialization and RPC protocol
                          s




                                                             s
                                                       all                                                                Other
                            TM




                                                     rc   RPC               over Ajax/HTTP requests            RPC
                                                  rve                                                                  Server-side
                               L




                                             se         /async                                                /impl
                                                                                                                       Components
                                   Boundary reads                                                                       & Entities

                                                                         transfer objects (both directions)
                                                                 DTO




                                                                  GWT Components




Bryan Basham – The Google Web Toolkit                                                                                                                           Slide 6
RJUG : 12-Mar-2012                                                                                                                            © Copyright 2013, Software Alchemy




                                           Typical GWT Architecture


                                          Desktop                                          Internet                         Server                         Database
          User

                                          ...........
                                          ...........
                                          ...........
             use
           gen




                                                                                                                                                            L
                                                                                                                                                         SQ
                 r ac
              e    rate

                     tion
                        sH




                                                                       GWT's serialization and RPC protocol        delegate to       CRUD
                          s




                                                             s
                                                       all
                            TM




                                                     rc   RPC               over Ajax/HTTP requests            RPC         Service           DAO
                                               rve
                               L




                                             se         /async                                                /impl




                                                                                                                                                s»
                                                                                                                                            a te
                                                                                                                                          re
                                   Boundary reads




                                                                                                                                        «c
                                                                         transfer objects (both directions)    ?
                                                                 DTO                                                             Entity




                                                                  GWT Components                                           Spring Components




Bryan Basham – The Google Web Toolkit                                                                                                                                      Slide 7
RJUG : 12-Mar-2012                                                                                                                              © Copyright 2013, Software Alchemy




                                           Typical GWT Architecture


                                          Desktop                                            Internet                         Server                         Database
          User

                                          ...........
                                          ...........
                                          ...........
             use
           gen




                                                                                                                                                              L
                                                                                                                                                           SQ
                 r ac
              e    rate

                     tion
                        sH




                                                                          GWT's serialization and RPC protocol       delegate to       CRUD
                          s




                                                           ll   s
                            TM




                                                        ca   RPC               over Ajax/HTTP requests            RPC        Service           DAO
                                                  rv er
                               L




                                             se            /async                                                /impl




                                                                                                                                                  s»
                                                                                                                                              a te
                                                                                                                                            re
                                   Boundary reads




                                                                                                                                          «c
                                                                                  into client-side DTO                   transforms
                                                                    DTO                                     Transformer               Entity




                                                                     GWT Components                                          Spring Components




Bryan Basham – The Google Web Toolkit                                                                                                                                        Slide 8
RJUG : 12-Mar-2012                                       © Copyright 2013, Software Alchemy




                                  Single-Page Web Apps

      ●     All of the GUI is built with GWT Java code,
            which becomes JavaScript at build-time
      ●     GWT provides a wide variety of panel widgets
            to hide complexity, such as:
                    –    Using a DeckLayoutPanel to manage a deck of
                          sub-panels in a wizard
                    –    Using a TabLayoutPanel to manage a complex
                          Domain model
      ●     Use the RootLayoutPanel object to build a GUI
            that dynamically resizes as the browser resizes
Bryan Basham – The Google Web Toolkit                                                 Slide 9
RJUG : 12-Mar-2012                                   © Copyright 2013, Software Alchemy




                                  SPWA Structure

      ●     The basic SPWA structure of a GWT app:
                    –    A single HTML file
                    –    One or more CSS files
                    –    An “entry point” class
                    –    And the web.xml, of course.




Bryan Basham – The Google Web Toolkit                                            Slide 10
RJUG : 12-Mar-2012                                               © Copyright 2013, Software Alchemy




                                  Example: GWT Root Page
  <!doctype html>
  <html>

       <head>
         <meta http-equiv="content-type" content="text/html; charset=UTF-8">
         <link type="text/css" rel="stylesheet" href="MyApp.css">
         <title>Web Application Starter Project</title>
         <script type="text/javascript" src="myapp/myapp.nocache.js"></script>
       </head>

       <body>

           <!-- OPTIONAL: include this if you want history support -->
           <iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1'
                  style="position:absolute;width:0;height:0;border:0"></iframe>

           <!-- Main View of the app -->
           <div id='view'></div>

       </body>

  </html>

Bryan Basham – The Google Web Toolkit                                                        Slide 11
RJUG : 12-Mar-2012                                        © Copyright 2013, Software Alchemy




                                  Example: Entry Point Class

      public class MyApp implements EntryPoint {
          /**
            * This is the entry point method.
            */
          public void onModuleLoad() {
               MyPresenter page = new MyPresenter();
               RootPanel.get("view").add(page.getView());
          }
      }

      ●     A GWT app could have many presenter/views
            but typically you will want to create a top-level
            view for the whole SPWA.
      ●     The MyApp is far too simple to need that, but
            the Alloy demo will demonstrate this
            architecture.
Bryan Basham – The Google Web Toolkit                                                 Slide 12
RJUG : 12-Mar-2012                                                                                            © Copyright 2013, Software Alchemy




                                  Model-View-Presenter

      ●     Similar to the popular Model-View-Controller
            pattern, but cleaner separation:
                                                                                                           ls
                                                                                                  e   r cal           RPC
                                                                                             serv                   /async
                                         user actions           signals events
                                        generates HTML   View    sends data      Presenter    reads
                       User

                                                                                                                      DTO

                    –    User interacts with the View
                    –    View interacts with the Presenter
                    –    Presenter interacts with the Model
                    –    Model provides:
                                 ●      communication with the Server using RPC
                                 ●      entity representation using DTOs
Bryan Basham – The Google Web Toolkit                                                                                                     Slide 13
RJUG : 12-Mar-2012                                                          © Copyright 2013, Software Alchemy




                                  Views

      ●     A View generates the HTML of the page and
            transfers user actions to the Presenter
      ●     A View is composed of three elements:
                    –    The UI-Binder config file (View.ui.xml)
                          declares the layout of the GUI's widgets
                    –    The Java file (View.java) provides the code to:
                                 ●      handle modifying the view when the model changes
                                 ●      handle user events from the browser
                    –    Any static support files, such as style sheets,
                          images and other media
Bryan Basham – The Google Web Toolkit                                                                   Slide 14
RJUG : 12-Mar-2012                                                           © Copyright 2013, Software Alchemy




                                  Example: View.ui.xml

      <!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
      <ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
        xmlns:g='urn:import:com.google.gwt.user.client.ui'>

         <g:HTMLPanel>
           <h1>Web Application Starter Project</h1>
           <table align="center">
             <tr>
               <td colspan="2" style="font-weight:bold;">Please enter your name:</td>
             </tr>
             <tr>
               <td id="nameFieldContainer">
                  <g:TextBox ui:field="nameField" />
               </td>
               <td id="sendButtonContainer">
                  <g:Button ui:field="sendButton">Send</g:Button>
               </td>
             </tr>
             <tr>
               <td colspan="2" style="color:red;" id="errorLabelContainer">
                  <g:Label ui:field="errorLabel" />
               </td>
             </tr>
           </table>
         </g:HTMLPanel>

      </ui:UiBinder>


Bryan Basham – The Google Web Toolkit                                                                    Slide 15
RJUG : 12-Mar-2012                                                              © Copyright 2013, Software Alchemy




                                  Example: View.java

      public class MyView extends Composite {

             interface MyUiBinder extends UiBinder<HTMLPanel, MyView> { }
             private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);

             @UiField Button sendButton;
             @UiField TextBox nameField;
             @UiField Label errorLabel;

             private final MyPresenter myPresenter;
             private final GreetingDialogBox dialogBox;

             public MyView(MyPresenter myPresenter) {
                 this.myPresenter = myPresenter;
                 this.dialogBox = new GreetingDialogBox(/* details skipped */);
                 // createAndBindUi initializes fields
                 initWidget(uiBinder.createAndBindUi(this));
                 // Focus the cursor on the name field when the app loads
                 nameField.setText("GWT User");
                 nameField.setFocus(true);
                 nameField.selectAll();
                 sendButton.addStyleName("sendButton");
             }

             // More code on next slide




Bryan Basham – The Google Web Toolkit                                                                       Slide 16
RJUG : 12-Mar-2012                                                     © Copyright 2013, Software Alchemy




                                  Example: View.java (part 2)

      public class MyView extends Composite {
          // More code on previous slide

             public void displayError(String message) {
                 errorLabel.setText(message);
             }
             public void showFailure(final String message) {
                 dialogBox.showFailure(message);
             }
             public void showSuccess(final String message) {
                 dialogBox.showSuccess(message);
             }

             @UiHandler("nameField")
             void handleEnterKey(final KeyUpEvent event) {
                 if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
                     sendNameToServer();
                 }
             }
             @UiHandler("sendButton")
             void handleSendBtn(final ClickEvent event) {
                 sendNameToServer();
             }

             // More code on next slide




Bryan Basham – The Google Web Toolkit                                                              Slide 17
RJUG : 12-Mar-2012                                                                © Copyright 2013, Software Alchemy




                                  Example: View.java (part 3)

      public class MyView extends Composite {
          // More code on previous slide

             private void sendNameToServer() {
                 // First, we validate the input.
                 errorLabel.setText("");
                 String name = nameField.getText();
                 if (!FieldVerifier.isValidName(name)) {
                     errorLabel.setText("Please enter at least four characters");
                     return;
                 }
                 // Then, we send the input to the server.
                 sendButton.setEnabled(false);
                 dialogBox.reset(name);
                 myPresenter.sendToServer(name);
             }
      }




Bryan Basham – The Google Web Toolkit                                                                         Slide 18
RJUG : 12-Mar-2012                                             © Copyright 2013, Software Alchemy




                                  Presenters

      ●     A Presenter component converts User actions,
            via the View, into Server-side commands using
            an RPC component.
      ●     A Presenter passes data from the Server to the
            Views, eg) a list of DTOs to a grid.
      ●     Presenter class should be free of View-related
            aspects (no interaction with widgets):
                    –    Makes the business-logic code cleaner
                    –    Permits simple unit-testing

Bryan Basham – The Google Web Toolkit                                                      Slide 19
RJUG : 12-Mar-2012                                                             © Copyright 2013, Software Alchemy




                                  Example: MyPresenter.java

      public class MyPresenter {

             /** Create a remote service proxy to talk to the server-side Greeting service. */
             private final GreetingServiceAsync greetingRPC =
                     GWT.create(GreetingService.class);
             private final MyView view;

             public MyPresenter() {
                 this.view = new MyView(this);
             }

             public MyView getView() {
                 return view;
             }

             public void sendToServer(final String name) {
                 greetingRPC.sayHello(name,
                         new AsyncCallback<String>() {
                     public void onFailure(Throwable caught) {
                         view.showFailure(SERVER_ERROR);
                     }
                     public void onSuccess(String result) {
                         view.showSuccess(result);
                     }
                 });
             }
      }


Bryan Basham – The Google Web Toolkit                                                                      Slide 20
RJUG : 12-Mar-2012                                                          © Copyright 2013, Software Alchemy




                                  Data Transfer Objects (DTO)

      ●     DTOs provide a client-side representation of
            the application's Domain Model
                    –    Basically just a JavaBean, with a no-arg ctor and
                          properties with get/set methods
                    –    Must implement the IsSerializable interface
                    –    Property values are limited to:
                                 ●      Java primitives and wrapper classes
                                 ●      Most java.util classes (Date, ArrayList, etc)
                                 ●      Other GWT-serializable DTO classes
      ●     Why not just use your Entity beans?
Bryan Basham – The Google Web Toolkit                                                                   Slide 21
RJUG : 12-Mar-2012                                          © Copyright 2013, Software Alchemy




                                  Remote Procedure Calls (RPC)

      ●     RPC components provide communication with
            the Server, much like Java's RMI
      ●     GWT's RPC mechanism requires:
                    –    The synchronous interface (MyRPC.java)
                    –    The implementation class (MyRPCImpl.java)
                    –    The asynchronous interface (MyRPCAsync.java)
      ●     The Presenter makes calls to RPC
            components using the asych interface
                    –    This is necessary because Ajax is used, which
                          requires callback functions
Bryan Basham – The Google Web Toolkit                                                   Slide 22
RJUG : 12-Mar-2012                                                                                                             © Copyright 2013, Software Alchemy




                                  RPC (Architecture Diagram)

                                                                         The Async interface is based upon the
                                                                         Sync interface but with an additional
                                                                         Callback<ReturnType> parameter.




                                                       «interface»                                                             «interface»
                                                       MyRPCAsync                                                                MyRPC
                                                                         This class implementation is provided
                                                                         by GWT which contains boiler-plate code
                                                                         to make Ajax requests.


                                        server calls               GWT's serialization and RPC protocol         delegates to
                       Boundary                          «class»        over Ajax/HTTP requests         GWT RPC                 «class»
                                                   MyRPCAsync_                                       servlet                   MyRPCImpl
                                                       impl

                                                                        GWT also provides a Servlet which:
                                                                        ● Handles the RPC requests

                                                                        ● De-serializes the arguments

                                                                        ● Delegates the RPC call to the appropriate

                                                                           RPC implementation
                                                                        ● Serializes the method return value




Bryan Basham – The Google Web Toolkit                                                                                                                      Slide 23
RJUG : 12-Mar-2012                                                      © Copyright 2013, Software Alchemy




                                  Example RPC Component

      ●     GreetingService interface:
      @RemoteServiceRelativePath("greet")
      public interface GreetingService extends RemoteService {
          String sayHello(String name) throws IllegalArgumentException;
      }


      ●     GreetingService implementation class:
      public class GreetingServiceImpl
      extends RemoteServiceServlet implements GreetingService {
          public String sayHello(String input) throws IllegalArgumentException {
              // Verify that the input is valid.
              if (!FieldVerifier.isValidName(input)) {
                  throw new IllegalArgumentException(
                          "Name must be at least 4 characters long");
              }
              String serverInfo = getServletContext().getServerInfo();
              String userAgent = getThreadLocalRequest().getHeader("User-Agent");
              return "Hello, " + input + "!<br><br>I am running " + serverInfo
                      + ".<br><br>It looks like you are using:<br>" + userAgent;
          }
      }

Bryan Basham – The Google Web Toolkit                                                               Slide 24
RJUG : 12-Mar-2012                                                       © Copyright 2013, Software Alchemy




                                  Example RPC Component (pt 2)

      ●     GreetingServiceAsync interface:
      public interface GreetingServiceAsync {
          void sayHello(String input, AsyncCallback<String> callback)
                  throws IllegalArgumentException;
      }


      ●     web.xml configuration:
          <servlet>
            <servlet-name>greetServlet</servlet-name>
            <servlet-class>com.example.myapp.server.GreetingServiceImpl</servlet-class>
          </servlet>
          <servlet-mapping>
            <servlet-name>greetServlet</servlet-name>
            <url-pattern>/myapp/greet</url-pattern>
          </servlet-mapping>




Bryan Basham – The Google Web Toolkit                                                                Slide 25
RJUG : 12-Mar-2012                                                                               © Copyright 2013, Software Alchemy




                                  RPC (Interaction Diagram)

           Boundary                        «class»    GWT RPC                         GWT RPC               «class»
                                        MyRPCAsync_   invoker                         servlet            MyRPCImpl
                                            impl

           sayHello(name, callback)

                                                            payload[sayHello|Fred]
                                                                                          sayHello(name)

                        name:String
                           “Fred”                                                          name:String
                                                                                              “Fred”

                              callback:
                        AsyncCallback<String>

                                                                                                return

                                                                payload[Hello Fred]
                                                                                          result:String
                                        onSuccess(result)                                  “Hello Fred”


                                           result:String
                                            “Hello Fred”



Bryan Basham – The Google Web Toolkit                                                                                        Slide 26
RJUG : 12-Mar-2012                                  © Copyright 2013, Software Alchemy




                                  GWT Configuration

      ●     A GWT project is organized into Java src and
            Webapp files in the war directory.
      ●     The MyApp.gwt.xml file is the
            primary config file.




Bryan Basham – The Google Web Toolkit                                           Slide 27
RJUG : 12-Mar-2012                                                                 © Copyright 2013, Software Alchemy




                                  GWT Configuration
      <!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.5.0//EN"
         "http://google-web-toolkit.googlecode.com/svn/tags/2.5.0/distro-source/core/src/gwt-module.dtd
      ">
      <module rename-to='myapp'>

          <!-- Inherit the core Web Toolkit stuff.                   -->
          <inherits name='com.google.gwt.user.User'/>

          <!-- Inherit the default GWT style sheet.    -->
          <inherits name='com.google.gwt.user.theme.clean.Clean'/>

          <!-- Specify the app entry point class.      -->
          <entry-point class='com.example.myapp.client.MyApp'/>

          <!-- Specify the paths for translatable code -->
          <source path='client'/>
          <source path='shared'/>

      </module>




Bryan Basham – The Google Web Toolkit                                                                          Slide 28
RJUG : 12-Mar-2012                                  © Copyright 2013, Software Alchemy




                                  GWT Configuration

      ●     The Java code is roughly organized into three
            packages:
                    –    client: on browser
                    –    server: on the server
                    –    shared: used on both sides




Bryan Basham – The Google Web Toolkit                                           Slide 29
RJUG : 12-Mar-2012                                                                                         © Copyright 2013, Software Alchemy




                                  Building Views
                                                               View
                                                                      Presenter
                                                      Model                         Like Java RMI
                                                                MVP                    ...but asynchronous
                                                                              RPC
                                               Single-Page
                                               Model
                                                                                  Config
                                                                Getting                                  Panels
                                                                                           Widgets
                                                                started
                                                DEMO #1                                                             Raw
                                                                             DEMO #2
                                                                                                                    Binding
                                    Using                                                     Building
                                  Data Grids                                                   Views
                                                                                                                    UI-Binding

                                                                                                     Styles / CSS
                                                               Google
                                                              Web Toolkit


                                  Extending                                                  Building
                                    GWT                                                     Presenters

                                                               Talking to
                                                               the Server




Bryan Basham – The Google Web Toolkit                                                                                                  Slide 30
RJUG : 12-Mar-2012                                                © Copyright 2013, Software Alchemy




                                  DEMO #2

      ●      Alloy is a Monitor & Control app on a document
             processing pathway:
          ....
          ..
          .....
          ....


    document1                                                 Datamart1
                                                                                          User
          ....
          ..
          .....                     Prospective   Warehouse
          ....


    document2

                                                              Datamart2
          ....
          ..
          .....
                                                                                          User
          ....


    document3


      ●      Also: search, reports, admin tools
Bryan Basham – The Google Web Toolkit                                                         Slide 31
RJUG : 12-Mar-2012                                            © Copyright 2013, Software Alchemy




                                  DEMO #2: Types of Pages

      ●     This app contains these types of pages:
                    –    Dashboards: shows high-level status & system
                          health
                    –    Monitor: view detail status and content flow
                    –    Control: modify system properties and other
                          actions
                    –    Search: tools to search on document content




Bryan Basham – The Google Web Toolkit                                                     Slide 32
RJUG : 12-Mar-2012                                    © Copyright 2013, Software Alchemy




                                  DEMO #2: Dashboards


Header

 Bread-
 crumb




 Pages
 Deck




 Footer
Bryan Basham – The Google Web Toolkit                                             Slide 33
RJUG : 12-Mar-2012                                      © Copyright 2013, Software Alchemy




                                  DEMO #2: Monitor page




Bryan Basham – The Google Web Toolkit                                               Slide 34
RJUG : 12-Mar-2012                                      © Copyright 2013, Software Alchemy




                                  DEMO #2: Control page




Bryan Basham – The Google Web Toolkit                                               Slide 35
RJUG : 12-Mar-2012                                           © Copyright 2013, Software Alchemy




                                  GWT Widgets

      ●     GWT provides basic HTML-based widgets
                    –    Button, Radio button, Checkbox, Listbox,
                          Textbox, Textarea, Hyperlink, and more
      ●     And some advanced widgets:
                    –    DatePicker, ToggleButton, CellList, MenuBar,
                          Tree, SuggestBox, RichTextArea, and more
      ●     Rich table/grid components
      ●     Click here: Widget Gallery


Bryan Basham – The Google Web Toolkit                                                    Slide 36
RJUG : 12-Mar-2012                                        © Copyright 2013, Software Alchemy




                                  Panels

      ●     Panels are complex <div> elements with
            behavior
      ●     Old-school panels to not handle browser
            resizing (and put the browser into quirks mode)
                    –    HorizontalPanel, VerticalPanel, StackPanel,
                          FlowPanel, DockPanel, PopupPanel, TabPanel
      ●     GWT v2 provides modern, resizable panels
                    –    DockLayoutPanel, DeckLayoutPanel,
                          TabLayoutPanel, ScrollPanel, LayoutPanel
                    –    ...and DataGrid
Bryan Basham – The Google Web Toolkit                                                 Slide 37
RJUG : 12-Mar-2012                                                       © Copyright 2013, Software Alchemy




                                  Resize-able UI

      ●     Fit the whole UI within the browser window
      ●     Use resize-able layouts from outside inward
      ●     Application.ui.xml:
      <ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
        xmlns:g='urn:import:com.google.gwt.user.client.ui'
        xmlns:alloy='urn:import:com.tr.cmg.alloy.ui.client.screen'>

          <g:DockLayoutPanel unit="PX">
            <g:north size="119"><alloy:Header ui:field="header" /></g:north>
            <g:center>
              <g:DockLayoutPanel unit="PX">
                <g:north size="29"><alloy:Breadcrumb ui:field="breadCrumb" /></g:north>
                <g:center><g:DeckLayoutPanel ui:field="pageDeck" /></g:center>
              </g:DockLayoutPanel>
            </g:center>
            <g:south size="30"><alloy:Footer ui:field="footer" /></g:south>
          </g:DockLayoutPanel>

      </ui:UiBinder>
Bryan Basham – The Google Web Toolkit                                                                Slide 38
RJUG : 12-Mar-2012                                                                           © Copyright 2013, Software Alchemy




                                  Alloy's Core GUI Architecture

      ●     Application contains many Pages with one
            View each:                  Extending this class forces each page
                                                «GWT Widget»
                                        view to be resize-able. It is the developer's
                                        responsibility to decide how the page's
                                                                                                 Resize
                                        layout is constructed to support resizing.              Composite




                                         1..*       «Presenter»                            1        «View»
      «GWT EntryPoint»
                                                     Abstract                                    Abstract
          Application                   pages                                           view
                                                      Page                                       PageView




                                                                    ...                                            ...
                                           «Presenter»                                     «View»
                                         Prospective                                     Prospective
                                        FeedLoadPage                                    FeedLoadView
Bryan Basham – The Google Web Toolkit                                                                                    Slide 39
RJUG : 12-Mar-2012                                           © Copyright 2013, Software Alchemy




                                  Raw UI-binding

      ●     GWT provides full access to the page's DOM
                    –    One-to-one methods for Element and Node APIs
                    –    Plus additional APIs to simplify common tasks,
                           like adding/removing CSS classes
      ●     GWT provides programmatic APIs to compose
            higher-level widgets (which encode DOM
            Elements)



Bryan Basham – The Google Web Toolkit                                                    Slide 40
RJUG : 12-Mar-2012                                    © Copyright 2013, Software Alchemy




                                  Raw UI-binding Techniques

      ●     Create strings of content and/or HTML tags
            and use setInnerHTML method.
      ●     Create Element objects and perform inserts
      ●     Create Widget objects and perform adds
      ●     Use raw binding sparingly; better to use the
            XML UI-binding config (as seen in other
            examples)



Bryan Basham – The Google Web Toolkit                                             Slide 41
RJUG : 12-Mar-2012                                       © Copyright 2013, Software Alchemy




                                  Raw UI-binding Example




Bryan Basham – The Google Web Toolkit                                                Slide 42
RJUG : 12-Mar-2012                                        © Copyright 2013, Software Alchemy




                                  Raw UI-binding Example

          <g:ScrollPanel>
            <g:HTMLPanel>
              <!-- Date selection form -->

                 <g:HTMLPanel ui:field="statsGrid">
                   <table border='1' cellpadding='5px'>
                     <thead>
                       <tr>
                         <th>Station</th>
                         <th>Category</th>
                         <th><!-- Date goes here --></th>
                         <th>Last 7 days</th>
                         <th>Last 30 days</th>
                         <th>Last 60 days</th>
                         <th>Last year</th>
                       </tr>
                     </thead>
                     <tbody>
                       <!-- View code fills the body -->
                     </tbody>
                   </table>
                 </g:HTMLPanel>

              <!-- Reload button form -->
            </g:HTMLPanel>
          </g:ScrollPanel>
Bryan Basham – The Google Web Toolkit                                                 Slide 43
RJUG : 12-Mar-2012                                                              © Copyright 2013, Software Alchemy




                                  Raw UI-binding Example

      public class DailyLoadStatsView extends AbstractPageView {
          // Skipping lots of other View code
          private void populateStatsGrid(final LoadStatsModelDTO loadStats) {
              final Document DOM = Document.get();
              List<String> categories = loadStats.getCategories();

                       // get TABLE element
                       Element gridEl = statsGrid.getElement();
                       Element tableEl = gridEl.getFirstChildElement();

                       // put date into "day" header
                       Element theadEl = tableEl.getFirstChildElement();
                       Element theadTR = theadEl.getFirstChildElement();
                       Element dateTH = theadTR.getFirstChildElement()
                                           .getNextSiblingElement().getNextSiblingElement();
                       Date reportDate = loadStats.getDailyLoadStats().getDateOfStats();
                       dateTH.setInnerText(DateUtils.asString(reportDate));

                       // More code on next slide
             }
      }




Bryan Basham – The Google Web Toolkit                                                                       Slide 44
RJUG : 12-Mar-2012                                                                © Copyright 2013, Software Alchemy




                                  Raw UI-binding Example

             private void populateStatsGrid(final LoadStatsModelDTO loadStats) {
                 // More code on previous slide

                       // build new TBODY
                       tbodyEl = DOM.createTBodyElement();
                       for (PathwayStation station : PathwayStation.values()) {
                           boolean first = true;
                           boolean odd = true;

                             // Add a row for each category
                             for (String category : categories) {
                                 TableRowElement rowEl = DOM.createTRElement();
                                 tbodyEl.appendChild(rowEl);
                                 rowEl.addClassName((odd) ? "odd" : "even");
                                 if (first) {
                                     // Insert the header on the first category for each station
                                     TableCellElement stationTH = DOM.createTHElement();
                                     stationTH.setInnerText(station.name());
                                     stationTH.setRowSpan(categories.size() + 1);
                                     rowEl.appendChild(stationTH);
                                     first = false;
                                 }
                             // Skipping the rest of the code (you get the point)
             }
      }

Bryan Basham – The Google Web Toolkit                                                                         Slide 45
RJUG : 12-Mar-2012                                                               © Copyright 2013, Software Alchemy




                                  XML UI-binding

      ●     Separation of concerns
                    –    View.ui.xml:
                                 ●      Layout of View widgets
                                 ●      Styles of widgets within the View
                    –    View.java:
                                 ●      Inject data into the View's widgets
                                 ●      Handle user events on the View's widgets
                    –    Other CSS files:
                                 ●      Styles of more generic aspects of the UI
                                 ●      Styles of custom widgets
Bryan Basham – The Google Web Toolkit                                                                        Slide 46
RJUG : 12-Mar-2012                                                       © Copyright 2013, Software Alchemy




                                  XML UI-binding Example

      <!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
      <ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
        xmlns:g='urn:import:com.google.gwt.user.client.ui'
        xmlns:c='urn:import:com.google.gwt.user.cellview.client'>      Widget libraries
        <ui:style>
         .body {
             margin: 1em;
         }
         .button {
             margin-top: 0 !important;             Page-specific CSS styles
             margin-bottom: 0 !important;
             margin-left: 0 !important;
             margin-right: 0.25em !important;
         }
         </ui:style>
        <g:DockLayoutPanel unit="EM" styleName="{style.body}">
          <g:north size="17">
            <!-- Search form -->     Fixed-width dock region
          </g:north>
          <g:center>
            <c:DataGrid ui:field='settingsGrid' />     Resize-able dock region
          </g:center>
        </g:DockLayoutPanel>
      </ui:UiBinder>


Bryan Basham – The Google Web Toolkit                                                                Slide 47
RJUG : 12-Mar-2012                                                                   © Copyright 2013, Software Alchemy




                                  XML UI-binding Example
            <!-- Search form -->
            <g:north size="17">
              <g:DockLayoutPanel unit="EM">
                <g:north size="2">
                  <g:FlowPanel width="100%">
                    <g:Label stylePrimaryName="alloyLabel">User Group:</g:Label>
                    <g:ListBox ui:field="userGroupList" stylePrimaryName="alloyLabel" width="250" />
                  </g:FlowPanel>
                </g:north>
                <g:center>
                  <g:DockLayoutPanel unit="EM">
                    <g:north size="2">
                       <g:FlowPanel width="100%">
                         <g:Label stylePrimaryName="alloyLabel">Content Set:</g:Label>
                         <g:ListBox ui:field="productList" stylePrimaryName="alloyLabel" width="250" />
                       </g:FlowPanel>
                    </g:north>
                    <g:center>
                       <g:FlowPanel width="100%">
                         <g:Label stylePrimaryName="alloyLabel">Collection:</g:Label>
                         <g:ListBox ui:field="collectionList"width="250" multipleSelect="true" />
                         <!-- Collection selection buttons -->
                         <g:Button ui:field="selectAllBtn">Select All</g:Button>
                         <g:HTML height="1px"> <br /> </g:HTML>
                         <g:Button ui:field="deselectAllBtn">Deselect All</g:Button>
                       </g:FlowPanel>
                    </g:center>
                  </g:DockLayoutPanel>
                <!-- More View config skipped to fit the slide -->
            </g:north>

Bryan Basham – The Google Web Toolkit                                                                            Slide 48
RJUG : 12-Mar-2012                                                     © Copyright 2013, Software Alchemy




                                  XML UI-binding Example

      public class FeedLoadSettingsView extends AbstractPageView {
          interface MyUiBinder extends UiBinder<DockLayoutPanel, FeedLoadSettingsView>{}
          private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
          /* Search criteria fields */
          @UiField ListBox userGroupList;
          @UiField ListBox productList;
          @UiField ListBox collectionList;
          @UiField Button selectAllBtn;
          @UiField Button deselectAllBtn;
          /* Action Buttons */
          @UiField Button searchBtn;
          @UiField Button saveBtn;
          @UiField Button resetBtn;
          /* Feed/Load Setting grid */
          @UiField(provided = true)
          DataGrid<FeedLoadSettingsDTO> settingsGrid;
          public FeedLoadSettingsView(final FeedLoadSettingsPage page) {
              super(page);
              // pre-binding initialization (“provides” the Grid object)
              initialize();
              // createAndBindUi initializes fields
              initWidget(uiBinder.createAndBindUi(this));
              // post-binding initialization
              userGroupList.getElement().setId(makeFieldId("userGroupList"));
      // Skipping more code to fit the slide

Bryan Basham – The Google Web Toolkit                                                              Slide 49
RJUG : 12-Mar-2012                                          © Copyright 2013, Software Alchemy




                                  View Styles

      ●     Use stand-alone CSS files for generic classes
            of styles; usually for custom widgets
      ●     Use UI-binding styles for Page-specific styles
      ●     Use programmatic controls to change styles at
            run-time
                    –    Do this sparingly
                    –    Favor changing classes rather than hard-coding
                          style values
                    –    Use GWT's getStyle().setXyzProperty()
                          as a last resort
Bryan Basham – The Google Web Toolkit                                                   Slide 50
RJUG : 12-Mar-2012                                                                                                © Copyright 2013, Software Alchemy




                                  Building Presenters
                                                               View
                                                                      Presenter
                                                      Model                         Like Java RMI
                                                                MVP                    ...but asynchronous
                                                                              RPC
                                               Single-Page
                                               Model
                                                                                  Config
                                                                Getting                                     Panels
                                                                                           Widgets
                                                                started
                                                DEMO #1                                                                   Raw
                                                                             DEMO #2
                                                                                                                          Binding
                                    Using                                                     Building
                                  Data Grids                                                   Views
                                                                                                                         UI-Binding

                                                                                                      Styles / CSS
                                                               Google
                                                              Web Toolkit
                                                                                                               Application
                                                                                                                           Error
                                  Extending                                                  Building                      Handling
                                    GWT                                                     Presenters                      Security

                                                                                                                    Dashboard
                                                               Talking to              History
                                                               the Server                           Pages
                                                                                                                     Search

                                                                                                             View
                                                                                               Form




Bryan Basham – The Google Web Toolkit                                                                                                         Slide 51
RJUG : 12-Mar-2012                                     © Copyright 2013, Software Alchemy




                                  Presenters == Business Logic

      ●     Application-level logic
                    –    Security constraints
                    –    Page management and flow
      ●     Page-level logic
                    –    Data management & caching
                    –    Validation
                    –    Server communication
      ●     Widget-level logic

Bryan Basham – The Google Web Toolkit                                              Slide 52
RJUG : 12-Mar-2012                                                                                 © Copyright 2013, Software Alchemy




                                  Application Entry-Point

      ●     GWT starts up and invokes the onModuleLoad
            method on the app's entry-point class:

                                                          «GWT EntryPoint»                            «RPC»
             GWT                        onModuleLoad        Application      getInitialState     ApplicationRPC




                                                               «DTO»                                  «DTO»
                                                            Application                             UserDTO
                                                             StateDTO
                                                                                               username : String
                                                       environment : String                    roles : Set<RoleDTO>
                                                       version : String
                                                       user : UserDTO
                                                       properties : Map<S,S>


Bryan Basham – The Google Web Toolkit                                                                                          Slide 53
RJUG : 12-Mar-2012                                                     © Copyright 2013, Software Alchemy




                                  Application Entry-Point

      public class Application implements EntryPoint {
          private static final ApplicationRPCAsync appRPC =
      ApplicationRPC.Util.getInstance();
          private static ApplicationStateDTO APP_STATE;
          public final void onModuleLoad() {
              initializeGUI();
          }
          public final void initializeGUI() {
              appRPC.getIntialState(new CallbackAdaptor<ApplicationStateDTO>() {
                  public void onSuccess(final ApplicationStateDTO appState) {
                      APP_STATE = appState;
                      propertyMap = appState.getPropertyMap();
                      buildNewGUI();
                      navigateToStartLocation(appState.getPlaceToStartCommand());
                  };
              });
          }
          private void buildNewGUI() {
              homePage = new AlloyHomePage(null);
              view = new ApplicationView(homePage);
              // Add the application View directly to the HTML <body>
              RootLayoutPanel.get().add(view);
              DOM.getElementById("alloy-loading").getStyle().setDisplay(Display.NONE);
          }
      }

Bryan Basham – The Google Web Toolkit                                                              Slide 54
RJUG : 12-Mar-2012                               © Copyright 2013, Software Alchemy




                                  Error Handling

      ●     RPC calls can throw Java exceptions
      ●     The AsyncCallback interface provides the
            onFailure method hook
      ●     The application can register an exception
            handler to handle these globally




Bryan Basham – The Google Web Toolkit                                        Slide 55
RJUG : 12-Mar-2012                                                              © Copyright 2013, Software Alchemy




                                  Error Handling

             public final void onModuleLoad() {
                 // Save the Singleton instance created by GWT
                 INSTANCE = this;

                       GWT.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
                           public void onUncaughtException(final Throwable error) {
                               if (error != null) {
                                   if (error.getCause() != null) {
                                        ErrorPopup.center(error.getCause());
                                   } else {
                                       ErrorPopup.center(error);
                                   }
                               } else {
                                   Log.error("Uncaught exception, but error is null");
                               }
                           }
                       });

                       initializeGUI();
             }




Bryan Basham – The Google Web Toolkit                                                                       Slide 56
RJUG : 12-Mar-2012                                    © Copyright 2013, Software Alchemy




                                  Alloy's Error Popup




Bryan Basham – The Google Web Toolkit                                             Slide 57
RJUG : 12-Mar-2012                                                           © Copyright 2013, Software Alchemy




                                  Application Security

      ●     The Application Singleton provides security
            query methods:
             public static boolean isUserInAnyRole(final RoleDTO... roles) {
                 for (RoleDTO role : roles) {
                     if (getCurrentUser().hasRole(role)) {
                         return true;
                     }
                 }
                 return false;
             }

      ●     Which are then used by Header to filter out
            specific menus or disable menu items:
             private MenuBar createMenuBar() {
                 MenuBar menubar = new MenuBar();
                 if (Application.isUserInRole(RoleDTO.ROLE_MONITOR)) {
                     menubar.addMenu(createProspectiveMenu());
                 }

Bryan Basham – The Google Web Toolkit                                                                    Slide 58
RJUG : 12-Mar-2012                                            © Copyright 2013, Software Alchemy




                                  Types of Pages

      ●     Alloy uses four basic types of pages:
                    –    Dashboards: shows high-level status & system
                          health
                    –    Monitor: view detail status and content flow
                    –    Control: modify system properties and other
                          actions
                    –    Search: tools to search on document content
      ●
            AbstractPage and AbstractDashboardPage
            provide basic features of Alloy pages

Bryan Basham – The Google Web Toolkit                                                     Slide 59
RJUG : 12-Mar-2012                                          © Copyright 2013, Software Alchemy




                                  GWT History Management

      ●     Because a GWT app is a single HTML page,
            user navigation is a little tricky
                    –    The browser's back button, for example, will
                          normally take you back to the page before you
                          entered the GWT app
                    –    GWT provides a hidden <iframe> to manage an
                          internal view transition management
                    –    GWT v2 provides a formal Places/Activities
                          framework, but not used in Alloy


Bryan Basham – The Google Web Toolkit                                                   Slide 60
RJUG : 12-Mar-2012                                                                                        © Copyright 2013, Software Alchemy




                                        Alloy's History Management
                                                                          «History Listener»
                GWT                          1:onValueChange
                                                                              HistoryCmd
                                                                               Manager
                                                                     e
                                                                   ag
                                                                eP       ge
                                                             ang       Pa
                                                            h        ge
                                                        T oC      an
                                                       k         h
                                                    2:o       4:c


                                                                                5:displayPage
                                       «Singleton»                                                          «Presenter»
                                       Application                                                             Page2




                                                                                                                             7:setState
                           3:isDirty




                                                                                                6:execute
                                          8:reset




                                                            currentPage


                                       «Presenter»                                                     Page2History
                                         Page1                                                        ChangeHandler


Bryan Basham – The Google Web Toolkit                                                                                                     Slide 61
RJUG : 12-Mar-2012                                                                                                   © Copyright 2013, Software Alchemy




                                  Talking to the Server
                                                               View
                                                                         Presenter
                                                      Model                            Like Java RMI
                                                                MVP                       ...but asynchronous
                                                                                 RPC
                                               Single-Page
                                               Model
                                                                                     Config
                                                                Getting                                        Panels
                                                                                              Widgets
                                                                started
                                                DEMO #1                                                                     Raw
                                                                                DEMO #2
                                                                                                                            Binding
                                    Using                                                        Building
                                  Data Grids                                                      Views
                                                                                                                            UI-Binding

                                                                                                         Styles / CSS
                                                               Google
                                                              Web Toolkit
                                                                                                                  Application
                                                                                                                              Error
                                  Extending                                                     Building                      Handling
                                    GWT                                                        Presenters                        Security

                                                                                                                       Dashboard
                                                               Talking to                 History
                                                               the Server                              Pages
                                              Thinking                                                                  Search
                                              Asynchronously                        Spring
                                                                                    Integration                 View
                                                                                                Form
                                                          DTOs &             Callback
                                                          Transformers       Adaptor


Bryan Basham – The Google Web Toolkit                                                                                                            Slide 62
RJUG : 12-Mar-2012                                                                                                                              © Copyright 2013, Software Alchemy




                                           Spring Integration

      ●     Remember the architecture:

                                          Desktop                                            Internet                         Server                         Database
          User

                                          ...........
                                          ...........
                                          ...........
             use
           gen




                                                                                                                                                              L
                                                                                                                                                           SQ
                 r ac
              e    rate

                     tion
                        sH




                                                                          GWT's serialization and RPC protocol       delegate to       CRUD
                          s




                                                           ll   s
                            TM




                                                        ca   RPC               over Ajax/HTTP requests            RPC        Service           DAO
                                                  rv er
                               L




                                             se            /async                                                /impl




                                                                                                                                                  s»
                                                                                                                                              a te
                                                                                                                                            re
                                   Boundary reads




                                                                                                                                          «c
                                                                                  into client-side DTO                   transforms
                                                                    DTO                                     Transformer               Entity




                                                                     GWT Components                                          Spring Components



Bryan Basham – The Google Web Toolkit                                                                                                                                       Slide 63
RJUG : 12-Mar-2012                                                      © Copyright 2013, Software Alchemy




                                  Spring Integration

      ●     Based upon a blog post by Chris Lee:
            GWT-RPC with Spring 2.x
      ●     Uses annotations on POJOs that implement
            the RPC sync interface:
      @GwtRpcEndPoint
      public class ProspectiveRPCImpl implements ProspectiveRPC { ... }

      ●     Eliminates web.xml configuration of RPC
            servlets but must include simple declarations in
            dispatcher-servlet.xml (see next slide)


Bryan Basham – The Google Web Toolkit                                                               Slide 64
RJUG : 12-Mar-2012                                                       © Copyright 2013, Software Alchemy




                                  Spring Integration

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans" ...>

          <bean
            class="org.springframework.web.servlet.mvc.anno.AnnoMethodHandlerAdapter" />

          <bean id="gwtAnnotationHandlerMapping"
            class="com.tr.cmg.alloy.ui.server.rpc.GwtAnnotationHandlerMapping"
            p:suffix=".rpc" p:prefix="/application/" p:order="1" />

          <bean id="urlMapping"
            class="org.springframework.web.servlet.mvc.annno.DefaultAnnoHandlerMapping"
            p:order="2" />

          <bean id="warehouseRPC"
            class="com.tr.cmg.alloy.ui.server.rpc.warehouse.WarehouseRPCImpl" />

          <bean id="delDatamartRPC"
            class="com.tr.cmg.alloy.ui.server.rpc.datamart.delivery.DelDatamartRPCImpl" />

          <!-- Many others... -->

      </beans>




Bryan Basham – The Google Web Toolkit                                                                Slide 65
RJUG : 12-Mar-2012                                           © Copyright 2013, Software Alchemy




                                  Callback Adaptor

      ●     The AsyncCallback has two methods:
                    –    onSuccess: successful response
                    –    onFailure: any HTTP error or service exception
      ●     But usually, you only care about onSuccess
      ●     So... create a CallbackAdaptor which
            implements the onFailure method
                    –    This is a good place to handle any expected
                          exceptions, such as security exceptions
                    –    Let unexpected exceptions be handled by the
                          Application-level global handler
Bryan Basham – The Google Web Toolkit                                                    Slide 66
RJUG : 12-Mar-2012                                                              © Copyright 2013, Software Alchemy




                                  Callback Adaptor
      public abstract class CallbackAdaptor<T> implements AsyncCallback<T> {
          @Override
          public void onFailure(final Throwable exception) {

                       if (exception instanceof SessionTimeoutException) {
                           MessageDialog.show(SESSION_TIMEOUT_MSG, GWT_RELOAD_ACTION);

                       } else if (exception instanceof GWTSecurityException) {
                           SecurityDialog.show((GWTSecurityException) exception, securityAction);

                       } else if (is404(exception)) {
                           MessageDialog.show(APPLICATION_REBOOT_MSG);

              } else if (exception.getMessage().contains(JDBC_CONNECTION_ERROR)) {
                  String message = "A connection to the database could not be
      established";
                  String alert = "Database Connection Alert";
                  ErrorPopup.center(alert, message, exception);

                       } else {
                           ErrorPopup.center(exception);
                       }
             }

             @Override
             public abstract void onSuccess(T result);
      }
Bryan Basham – The Google Web Toolkit                                                                       Slide 67
RJUG : 12-Mar-2012                                         © Copyright 2013, Software Alchemy




                                  Callback Decorators

      ●     Do not embed too much extraneous logic in
            callback methods
      ●     Rather use the Decorator pattern to wrap the
            primary callback with additional behavior
      ●     Alloy provides several decorators:
                    –    ServerWaitDecorator: provides the screen
                              mask
                    –    LoggingDecorator: provides logging of the
                              result
                    –    Lots of other possibilities...
Bryan Basham – The Google Web Toolkit                                                  Slide 68
RJUG : 12-Mar-2012                                                      © Copyright 2013, Software Alchemy




                                  Callback Decorator Example

      public final class ServerWaitDecorator<T> extends CallbackDecorator<T> {
          public ServerWaitDecorator(final String maskText,
                                      final AsyncCallback<T> wrappedCallback) {
              super(Preconditions.checkNotNull(wrappedCallback));
              // Start the masking process
              startMask(maskText);
          }
          @Override
          public void onFailure(final Throwable caught) {
              stopMask(); // Stop the masking process
              super.onFailure(caught);
          }
          @Override
          public void onSuccess(final T result) {
              stopMask(); // Stop the masking process
              super.onSuccess(result);
          }
          private void startMask(final String maskText) {
              ServerWaitPopup.show(maskText);
          }
          private void stopMask() {
              ServerWaitPopup.hide();
          }
      }


Bryan Basham – The Google Web Toolkit                                                               Slide 69
RJUG : 12-Mar-2012                                                        © Copyright 2013, Software Alchemy




                                  Callback Decorator Example

      // request settings from the Server
      AsyncCallback<List<FeedLoadSettingsDTO>> callbackChain =
              new CallbackAdaptor<List<FeedLoadSettingsDTO>>() {
          @Override
          public void onSuccess(final List<FeedLoadSettingsDTO> result) {
              settings = result;
              getView(FeedLoadSettingsView.class).setSettingsData(settings);
              // reset book-keeping data structures
              resetChanges();
          }
      };
      // decorate the callback
      callbackChain = new ServerWaitDecorator<List<FeedLoadSettingsDTO>>(
              "Retrieving settings; please wait...", callbackChain);

      // invoke the RPC call
      prospectiveRPC.retrieveFeedLoadSettings(Arrays.asList(collections),
              callbackChain);




Bryan Basham – The Google Web Toolkit                                                                 Slide 70
RJUG : 12-Mar-2012                                           © Copyright 2013, Software Alchemy




                                  DTOs and Transformers

      ●     You could pass server-side Entity POJOs
            across the GWT RPC “wire”, but...
                    –    Muddies Entities with GWT-specific interface
                    –    Must be in the “GWT shared” package
      ●     If you are using Hibernate and/or JPA, then
            Entity POJOs are decorated with objects that
            are not GWT-serializable
      ●     Thus, I recommend separating Entity and
            DTOs and using transformers at the RPC tier

Bryan Basham – The Google Web Toolkit                                                    Slide 71
RJUG : 12-Mar-2012                                             © Copyright 2013, Software Alchemy




                                  DTOs and Transformers

      ●     Furthermore, there could be real differences
            between the Entity and DTO classes
                    –    Entity classes might have much more data than
                          the client-side DTO needs
                    –    DTO might have methods that are unique to the
                          needs of the View or Presenter components
      ●     Transformers are basically implementations of
            the Guava Function<T,F> interface
                    –    Only need to transform individuals
                    –    Let GWT's serializer handle lists, sets, maps, etc
Bryan Basham – The Google Web Toolkit                                                      Slide 72
RJUG : 12-Mar-2012                                                        © Copyright 2013, Software Alchemy




                                  Transformer Example

      @GwtRpcEndPoint
      public class ProspectiveRPCImpl implements ProspectiveRPC {

             @Autowired
             private ProspectiveService proService;

             private final Function<ProspectiveHealth, ProspectiveHealthDTO> healthTFM =
                     new Function<ProspectiveHealth, ProspectiveHealthDTO>() {
                 @Override
                 public ProspectiveHealthDTO apply(@Nullable ProspectiveHealth input) {
                     return new ProspectiveHealthDTO(
                             input.getRequestProcessorHost(),
                             input.getWorkGeneratorHost(),
                             input.getFinalizerHost(),
                             input.getCleanupHost(),
                             input.getCleanupTimestamp());
                 }
             };

             public ProspectiveHealthDTO getStationHealth(boolean forceRefresh) {
                 // Delegate to Service
                 ProspectiveHealth entity = proService.getStationHealth(forceRefresh);
                 // Transform to client-side representation
                 return healthTFM.apply(entity);
             }
      }
Bryan Basham – The Google Web Toolkit                                                                 Slide 73
RJUG : 12-Mar-2012                                                        © Copyright 2013, Software Alchemy




                                  Thinking Asynchronously

      ●     Any event-driven environment, such as a user
            interface, requires the developer to think
            asynchronously.
      ●     A web UI is doubly so because of the use of
            Ajax and therefore callbacks to handle the
            server response.
      ●     What's wrong with this?
             public void preparePage(final HistoryCommand pendingHistoryCmd) {
                 retrievePathwayConfigFromServer();
                 retrieveUserGroupsFromServer();
                 sendSearchRequestToServer();
             }



Bryan Basham – The Google Web Toolkit                                                                 Slide 74
RJUG : 12-Mar-2012                                                               © Copyright 2013, Software Alchemy




                                  Thinking Asynchronously
            public void preparePage(final HistoryCommand pendingHistoryCmd) {
                AsyncCallback<PathwayConfigurationDTO> firstCallback =
                        new CallbackAdaptor<PathwayConfigurationDTO>() {
                    @Override
                    public void onSuccess(PathwayConfigurationDTO result) {
                        // store pathway config
                        pathwayConfig = result;
                        // next get the user groups
                        AsyncCallback<List<UserGroupDTO>> secondCallback =
                                new CallbackAdaptor<List<UserGroupDTO>>() {
                            @Override
                            public void onSuccess(List<UserGroupDTO> result) {
                                // store user groups
                                userGroups = result;
                                // finally send the search request
                                AsyncCallback<List<String>> thirdCallback =
                                        new CallbackAdaptor<List<String>>() {
                                    @Override
                                    public void onSuccess(List<String> result) {
                                        // send search to the View
                                        getView().displaySearch(result);
                                    }
                                };
                                myRPC.sendSearchRequest(thirdCallback);
                            }
                        };
                        myRPC.retrievePathwayConfig(secondCallback);
                    }
                };
                myRPC.retrievePathwayConfig(firstCallback);
            }

Bryan Basham – The Google Web Toolkit                                                                        Slide 75
RJUG : 12-Mar-2012                                                                                                   © Copyright 2013, Software Alchemy




                                  Extending GWT
                                                               View
                                                                         Presenter
                                                      Model                            Like Java RMI
                                                                MVP                       ...but asynchronous
                                                                                 RPC
                                               Single-Page
                                               Model
                                                                                     Config
                                                                Getting                                        Panels
                                                                                              Widgets
                                                                started
                                                DEMO #1                                                                     Raw
                                                                                DEMO #2
                                                                                                                            Binding
                                    Using                                                        Building
                                  Data Grids                                                      Views
                                                                                                                            UI-Binding

                                                                                                         Styles / CSS
                                                               Google
                                                              Web Toolkit
                   Dialog
                                                                                                                  Application
                   Gadgets
                                                                                                                              Error
                                  Extending                                                     Building                      Handling
              Complex
              Widget                GWT                                                        Presenters                      Security
                   Simple                                                                                              Dashboard
                   Widget                                      Talking to                 History
                                Widgets &                      the Server                              Pages
                                Gadgets       Thinking                                                                  Search
                                              Asynchronously                        Spring
                                                                                    Integration                 View
                                                                                                Form
                                                          DTOs &             Callback
                                                          Transformers       Adaptor


Bryan Basham – The Google Web Toolkit                                                                                                            Slide 76
RJUG : 12-Mar-2012                                          © Copyright 2013, Software Alchemy




                                  Widgets and Gadgets

      ●     Every non-trivial application will need to have
            custom widgets and gadgets.
      ●     My definitions:
                    –    A widget is a GUI component that is meant to be
                           embedded within other GUI components or
                           panels, such as a custom drop-down list
                    –    A gadget is a standalone GUI component, such
                           as a dialog box



Bryan Basham – The Google Web Toolkit                                                   Slide 77
RJUG : 12-Mar-2012                                                        © Copyright 2013, Software Alchemy




                                  A Simple Widget

      ●     GWT's ListBox widget does not support rich,
            HTML text in the options, so I build one that
            does:
      /**
       * An enhancement to the GWT {@link ListBox} widget in which the option text is
       * rendered as raw HTML. This allows the developer to provide rich text in the
       * drop-down list.
       */
      public class AlloyListBox extends ListBox {

             @Override
             protected void setOptionText(OptionElement opt, String text, Direction dir) {
                 opt.setInnerHTML(text);
             }

      }




Bryan Basham – The Google Web Toolkit                                                                 Slide 78
RJUG : 12-Mar-2012                                                     © Copyright 2013, Software Alchemy




                                  A Complex Widget – Problem

      ●     GWT's ListBox widget only supports text
            values. It just mimics the HTML <select>
            element. For example:
             @UiField ListBox userGroupList;

             @UiHandler("userGroupList")                           The getItemText method
             final void selectUserGroup(final ChangeEvent e) {     returns a String.
                 String group;
                 if (userGroupList.getSelectedIndex() == 0) {
                     group = null;
                 } else {
                     group = userGroupList.getItemText(userGroupList.getSelectedIndex());
                 }
                 getPage(FeedLoadSettingsPage.class).setSelectedGroup(group);
                 // update Product list
                 List<String> products = null;
                 if (group != null) {
                     products = getPage(FeedLoadSettingsPage.class).getProducts(group);
                 }
                 initProductList(products);
             }
Bryan Basham – The Google Web Toolkit                                                              Slide 79
RJUG : 12-Mar-2012                                                        © Copyright 2013, Software Alchemy




                                  A Complex Widget – Solution

      ●     So, I built a drop-down widget that allows the
            developer to hold any type of object.
      ●     Example now transformed to:
                                                                   The getValue method
             @UiField DropDownList<UserGroupDTO> userGroupList;    returns an Object of the
             @UiHandler("userGroupList")                           the desired type.
             final void selectUserGroup(final ValueChangeEvent<UserGroupDTO> event) {
                 UserGroupDTO group = event.getValue();
                 getPage(FeedLoadSettingsPage.class).setSelectedGroup(group);
                 // update Product list
                 List<String> products = null;
                 if (group != null) {
                     products = getPage(FeedLoadSettingsPage.class).getProducts(group);
                 }
                 initProductList(products);
             }



Bryan Basham – The Google Web Toolkit                                                                 Slide 80
RJUG : 12-Mar-2012                                                     © Copyright 2013, Software Alchemy




                                  DropDownList – Implementation

      ●     DropDownList list management:
      public class DropDownList<T> extends FocusWidget               Favor composition
      implements HasValueChangeHandlers<T> {                         over inheritance.
          private final ListBox selectWidget;
          private T selectedItem;
          private Function<T, String> valueFunction;
          private Function<T, String> textFunction;
          private final Map<String, T> valueToItemMap = Maps.newHashMap();

          public void addItem(T item) {
              String text = textFunction.apply(item);
              String value = valueFunction.apply(item);
              // validate a non-empty value (reserved for "null" item)
              if (value.isEmpty()) {
                  throw new IllegalArgumentException("The Option '" + text + "' has an
      empty value.");
              }
              // add to <select> element and book-keeping
              selectWidget.addItem(text, value);
              valueToItemMap.put(value, item);
          }
      }


Bryan Basham – The Google Web Toolkit                                                              Slide 81
RJUG : 12-Mar-2012                                                     © Copyright 2013, Software Alchemy




                                  DropDownList – Implementation

      ●     DropDownList declaration:                            The internal ListBox
      public class DropDownList<T> extends FocusWidget           change handler dispatches
      implements HasValueChangeHandlers<T> {                     to the DropDownList
          private final ListBox selectWidget;
          private ListBox makeListBox() {
                                                                 value change handlers.
              ListBox widget = new ListBox(false);
              widget.addChangeHandler(new ChangeHandler() {
                  public void onChange(ChangeEvent event) {
                      final int selectedIdx = selectWidget.getSelectedIndex();
                      final String valueText = selectWidget.getValue(selectedIdx);
                      if (Strings.isNullOrEmpty(valueText)) {
                          fireValueChangeEvent(null);
                      } else {
                          fireValueChangeEvent(valueToItemMap.get(valueText));
                      }
                  }
              });
              return widget;
          }
          private void fireValueChangeEvent(final T newValue) {
              ValueChangeEvent.fireIfNotEqual(this, selectedItem, newValue);
              selectedItem = newValue;
          }
      }
Bryan Basham – The Google Web Toolkit                                                              Slide 82
RJUG : 12-Mar-2012                               © Copyright 2013, Software Alchemy




                                  Dialog Gadgets

      ●     GWT comes with a PopupPanel component but
            nothing like a “confirmation dialog.”




Bryan Basham – The Google Web Toolkit                                        Slide 83
RJUG : 12-Mar-2012                                                              © Copyright 2013, Software Alchemy




                                  Confirmation Dialog Example

      ●     The Prospective Dashboard popup menu uses
            the confirmation dialog like so:
                       pauseItem = addMenuItem(PAUSE_MENU_LABEL, new Command() {
                           public void execute() {
                               ConfirmationDialog.show(PAUSE_CONFIRMATION_MSG, pauseCmd);
                           }
                       }, Application.CONTROL_ROLES);

      ●     The ConfirmationDialog is a Singleton with
            static method API to show the dialog.
                    –    It takes a message and a GWT Command object
                            that is invoke if the user clicks the “Ok” button.


Bryan Basham – The Google Web Toolkit                                                                       Slide 84
RJUG : 12-Mar-2012                                                         © Copyright 2013, Software Alchemy




                                  Confirmation Dialog Example

      public final class ConfirmationDialog {

             public interface Callback {
                 void onOk();
                 void onCancel();
             }

             public abstract static class SimpleCallback implements Callback {
                 public void onCancel() { }
             }

             // Singleton pattern
             private static final ConfirmationDialog INSTANCE = new ConfirmationDialog();
             static {
                 RootPanel.get().add(INSTANCE.view);
             }
             private ConfirmationDialog() { }

             // Attributes
             private final ConfirmationView view = new ConfirmationView();

             // The “show” methods on next slide
      }




Bryan Basham – The Google Web Toolkit                                                                  Slide 85
RJUG : 12-Mar-2012                                                        © Copyright 2013, Software Alchemy




                                  Confirmation Dialog Example

      public final class ConfirmationDialog {

             // More code on previous slide

             public static void show(final String title,
                     final String message,
                     final Callback callback) {
                 INSTANCE.view.show(title, message, callback);
             }

             public static void show(final String message, final Callback callback) {
                 show("Please Confirm", message, callback);
             }

             public static void show(final String message, final Command okCommand) {
                 show("Please Confirm", message, new SimpleCallback() {
                     @Override
                     public void onOk() {
                         okCommand.execute();
                     }
                 });
             }
      }




Bryan Basham – The Google Web Toolkit                                                                 Slide 86
RJUG : 12-Mar-2012                                                        © Copyright 2013, Software Alchemy




                                  Confirmation Dialog View

      public class ConfirmationView extends AlloyPopupPanel {
          private static final String DIALOG_ID = "confirmationDialog";

             interface MyUiBinder extends UiBinder<VerticalPanel, ConfirmationView> { }
             private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);

             @UiField          Label titleLabel;
             @UiField          HTML messageText;
             @UiField          Button okButton;
             @UiField          Button cancelButton;

             ConfirmationView() {
                 super(false, true);
                 setWidget(uiBinder.createAndBindUi(this));
                 getElement().setId(DIALOG_ID);
                 getElement().getStyle().setWidth(250, Style.Unit.PX);
             }

             final void show(String title, String message, Callback c) {
                 titleLabel.setText(title);
                 messageText.setWordWrap(true);
                 messageText.setHTML(message);
                 callback = c;
                 center();
             }
             // The button handler methods on next slide
Bryan Basham – The Google Web Toolkit                                                                 Slide 87
RJUG : 12-Mar-2012                                                     © Copyright 2013, Software Alchemy




                                  Confirmation Dialog View

      public class ConfirmationView extends AlloyPopupPanel {
          // More code on previous slide
          @UiHandler("okButton")
          final void handleOk(final ClickEvent e) {
              callback.onOk();
              hide();
          }
          @UiHandler("cancelButton")
          final void handleCancel(final ClickEvent e) {
              callback.onCancel();
              hide();
          }
      }

      <ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
        xmlns:g='urn:import:com.google.gwt.user.client.ui'>
        <g:VerticalPanel>
          <g:Label ui:field="titleLabel" styleName="title">Please Confirm</g:Label>
          <g:HTML ui:field="messageText" styleName="body" />
          <g:FlowPanel styleName="buttons">
            <g:Button ui:field="okButton">Ok</g:Button>
            <g:Button ui:field="cancelButton">Cancel</g:Button>
          </g:FlowPanel>
        </g:VerticalPanel>
      </ui:UiBinder>

Bryan Basham – The Google Web Toolkit                                                              Slide 88
RJUG : 12-Mar-2012                                                       © Copyright 2013, Software Alchemy




                                  Alloy's Popup Panel Class

      public abstract class AlloyPopupPanel extends PopupPanel {
          protected AlloyPopupPanel(final boolean autoHide, final boolean modal) {
              super(autoHide, modal);
              addStyleName("AlloyPopup");
          }
      }

      // in Application.css (provides the border and drop-shadow effect)
      div.AlloyPopup {
         background-color: #FFFFFF;
          border-color: #CECECE #BABABA #888888 #CECECE;
          border-width: 1px;
          border-style: solid;
          border-radius: 7px;
          box-shadow: 10px 10px 5px #75b2d5;
      }




Bryan Basham – The Google Web Toolkit                                                                Slide 89
RJUG : 12-Mar-2012                                                                                                   © Copyright 2013, Software Alchemy




                                  Using Data Grids
                                                               View
                                                                         Presenter
                                                      Model                            Like Java RMI
                                                                MVP                       ...but asynchronous
                                                                                 RPC
                                               Single-Page
                                               Model
                                                                                     Config
                                                                Getting                                        Panels
                                                                                              Widgets
                        Edit Grids                              started
                                                DEMO #1                                                                     Raw
               Paging                                                           DEMO #2
                                                                                                                            Binding
                                    Using                                                        Building
                                  Data Grids                                                      Views
                Sorting
                                                                                                                            UI-Binding
                       DataGrid
                       Basics                                                                            Styles / CSS
                                                               Google
                                                              Web Toolkit
                   Dialog                                                                                         Application
                   Gadgets
                                                                                                                              Error
                                  Extending                                                     Building                      Handling
              Complex
              Widget                GWT                                                        Presenters                        Security
                   Simple                                                                                              Dashboard
                   Widget                                      Talking to                 History
                                Widgets &                      the Server                              Pages
                                Gadgets       Thinking                                                                  Search
                                              Asynchronously                        Spring
                                                                                    Integration                 View
                                                                                                Form
                                                          DTOs &             Callback
                                                          Transformers       Adaptor


Bryan Basham – The Google Web Toolkit                                                                                                            Slide 90
RJUG : 12-Mar-2012                                          © Copyright 2013, Software Alchemy




                                  The DataGrid Basics

      ●     Two GWT widgets for HTML tables:
                    –    CellTable is an ordinary <table>
                    –    DataGrid is a resize-able grid where the body
                          is scrollable
      ●     Grids may have headers and footers
      ●     Grid columns may support sorting
      ●     Grids may support client-side and server-side
            paging using the SimplePager widget
      ●     Grids can be editable
Bryan Basham – The Google Web Toolkit                                                   Slide 91
RJUG : 12-Mar-2012                                                                                                    © Copyright 2013, Software Alchemy




                                  The DataGrid Basics

                                            R is the data type of the                    C is the data type of the
                                            contents of each row in the grid.            contents of a single column.




                                        R                                             R, C                                              C
                                                            1..*                                            1
                 DataGrid                                                Column                                         Cell
                                                        columns                                         cell




                                        R                               R, C=String                                  C=Number
                                                                                       ...                                                ...

             AlloyDataGrid                                 TextColumn                                   NumberCell




Bryan Basham – The Google Web Toolkit                                                                                                             Slide 92
RJUG : 12-Mar-2012                                    © Copyright 2013, Software Alchemy




                                  Example Simple Grid


                                           Header




                                           Footer



Bryan Basham – The Google Web Toolkit                                             Slide 93
RJUG : 12-Mar-2012                                                        © Copyright 2013, Software Alchemy




                                  Example Simple Grid

      public class MonitorView extends AbstractPageView {

             @UiField(provided = true)
             AlloyDataGrid<MonitorOverviewDTO> overviewGrid;

             void populateOverviewGrid(final List<MonitorOverviewDTO> dtos) {
                 overviewGrid.setRowData(dtos);
             }

             private void initialize() {
                 // initialize Overview tab grid
                 overviewGrid = new AlloyDataGrid<MonitorOverviewDTO>("overviewGrid");
                 overviewGrid.setWidth("75%");
                 // Date column
                 TextColumn<MonitorOverviewDTO> dateColumn = new TextColumn<...>() {
                     @Override
                     public String getValue(final MonitorOverviewDTO row) {
                         return DateUtils.asString(row.getDate());
                     }
                 };
                 dateColumn.setCellStyleNames("columnLeft");
                 overviewGrid.addColumn(dateColumn, "Date");
                 overviewGrid.setColumnWidth(dateColumn, DATE_COLUMN_SIZE, Unit.PCT);
                 // ... more column definitions on next slide
             }

Bryan Basham – The Google Web Toolkit                                                                 Slide 94
RJUG : 12-Mar-2012                                                     © Copyright 2013, Software Alchemy




                                  Simple Grid – Column w/ Footer

    public class MonitorView extends AbstractPageView {
        private void initialize() {
              // column definition with Footer
              Column<MonitorOverviewDTO, Number> workflowsColumn =
                      new Column<MonitorOverviewDTO, Number>(
                      new NumberCell()) {
                  @Override
                  public Number getValue(final MonitorOverviewDTO row) {
                      return row.getWorkflows();
                  }
              };
              Header<Number> workflowsFooter = new Header<Number>(new NumberCell()) {
                  public Number getValue() {
  A footer is         int sum = 0;
  defined by a        for (MonitorOverviewDTO row : overviewGrid.getVisibleItems()) {
                          sum += row.getWorkflows();
  Header object. }
  Go figure!          return sum;
                  }
              };
              overviewGrid.addColumn(workflowsColumn,
                      new SafeHtmlHeader(SafeHtmlUtils.fromTrustedString("Workflows")),
                      workflowsFooter);
              overviewGrid.setColumnWidth(workflowsColumn, WORKFLOW_COL_SIZE, Unit.PCT);
        }

Bryan Basham – The Google Web Toolkit                                                              Slide 95
RJUG : 12-Mar-2012                                          © Copyright 2013, Software Alchemy




                                  Grids with Sortable Columns

      ●     Grid columns may support sorting
      ●     Grid contains a “sort handler”
      ●     Use a “data provider” and sort its list using a
            Java Comparator
                    –    Need a comparator for the whole grid; must
                          handle ascending and descending
                    –    Need a comparator for each column that
                          supports sorting


Bryan Basham – The Google Web Toolkit                                                   Slide 96
RJUG : 12-Mar-2012                                         © Copyright 2013, Software Alchemy




                                  Grid Sorting – Screenshot

                                            Ascending icon




Bryan Basham – The Google Web Toolkit                                                  Slide 97
RJUG : 12-Mar-2012                                                          © Copyright 2013, Software Alchemy




                                  Grid Sorting – Data Provider

      public class MonitorView extends AbstractPageView {
                                                             Create a data provider.
             @UiField(provided = true)
             AlloyDataGrid<MonitorOverviewDTO> overviewGrid;
             private final ListDataProvider<MonitorOverviewDTO> dataProvider =
                     new ListDataProvider<MonitorOverviewDTO>();

             void populateOverviewGrid(final List<MonitorOverviewDTO> dtos) {
                 // sort new list
                 Collections.sort(dtos, gridComparator);
                 // refresh the view
                 dataProvider.setList(dtos);                  Sort the data provider.
                 overviewGrid.setVisibleRange(0, dtos.size());
             }

             private void initialize() {
                 // initialize Overview tab grid
                 overviewGrid = new AlloyDataGrid<MonitorOverviewDTO>("overviewGrid");
                 overviewGrid.setWidth("75%");
                 overviewGrid.addColumnSortHandler(contentSortHandler);
                 dataProvider.addDataDisplay(overviewGrid);

       Attach grid to data provider.                           Attach a column sort handler.


Bryan Basham – The Google Web Toolkit                                                                   Slide 98
RJUG : 12-Mar-2012                                                              © Copyright 2013, Software Alchemy




                                  Grid Sorting – Grid Comparator

      public class MonitorView extends AbstractPageView {

             private static class GridSortComparator
                            implements Comparator<MonitorOverviewDTO> {

                       // default sort: by Date column ascending
                       private ColumnComparator columnComp = ColumnComparator.DATE;
                       private boolean isAscending = true;

                       @Override
                       public int compare(MonitorOverviewDTO o1, MonitorOverviewDTO o2) {
                           int ascCompare = columnComp.compare(o1, o2);
                           if (!isAscending) {
                               ascCompare *= -1; // reverse if descending
                           }
                           return ascCompare;
                       }
             }

             private final GridSortComparator gridComparator = new GridSortComparator();




Bryan Basham – The Google Web Toolkit                                                                       Slide 99
RJUG : 12-Mar-2012                                                        © Copyright 2013, Software Alchemy




                                  Grid Sorting – Column
                                  Comparators as an Enum
      public class MonitorView extends AbstractPageView {

             enum ColumnComparator implements Comparator<MonitorOverviewDTO> {
                 DATE() {
                     public int compare(MonitorOverviewDTO o1, MonitorOverviewDTO o2) {
                         return o1.getDate().compareTo(o2.getDate());
                     }
                 },
                 WORKFLOWS() {
                     public int compare(MonitorOverviewDTO o1, MonitorOverviewDTO o2) {
                         return o1.getWorkflows() - o2.getWorkflows();
                     }
                 },
                 DOCUMENTS() {
                     public int compare(MonitorOverviewDTO o1, MonitorOverviewDTO o2) {
                         return (int) (o1.getDocuments() - o2.getDocuments());
                     }
                 }
             }




Bryan Basham – The Google Web Toolkit                                                                Slide 100