SlideShare a Scribd company logo
GWT + HTML5
    GTUG Atlanta
    David Chandler drfibonacci@google.com
    Philip Rogers pdr@google.com




Thursday, June 30, 2011                     1
Agenda

  •     Overview
  •     Local Storage for performance
  •     Visualizations via Canvas
  •     Enrich your app with Audio
  •     Embedding Video in your app
  •     Drag and Drop support
  •     Handling unsupported browser versions
  •     CSS3 makes its way into GWT
  •     Angry Birds / ForPlay




Thursday, June 30, 2011                         2
Overview

  • What to expect
    o Lots of demos
    o Lots of code examples
  • What you will learn
    o How to use HTML5 in your GWT app




Thursday, June 30, 2011                  3
Overview
    What is HTML5?
   • HTML5 includes lots of stuff
      o Media rich DOM elements
      o Useful new APIs
      o CSS3 enhancements
   • Support is increasing very rapidly
   • Embrace it to make your apps stand out




Thursday, June 30, 2011                       4
Why now?




Thursday, June 30, 2011   5
Why now?




                          Hint:



Thursday, June 30, 2011           6
HTML5 for Designers


                    header,nav,footer -- more semantic meaning
                    aside concept
                    HSL color
                    @font-face
                    border-radius
                    transforms, transitions
                    Canvas
                    HTML5 video player (sans Flash)




Thursday, June 30, 2011                                          7
HTML5 for Programmers
                     • WebSockets
                     • Client-side storage
                        o LocalStorage API
                        o Web SQL (it's dead, Jim)
                        o indexedDB
                     • Web Workers
                     • form fields
                        o type=email,date,range,search,tel,color,...
                     • <meter>,<progress>
                     • app cache
                     • notifications
                     • geolocation
                     • device orientation
                     • server side events



Thursday, June 30, 2011                                                8
HTML5 support


                          http://www.html5rocks.com/


                             http://html5test.com




Thursday, June 30, 2011                                9
Agenda

  •     Overview
  •     Local Storage for performance
  •     Visualizations via Canvas
  •     Enrich your app with Audio
  •     Embedding Video in your app
  •     Drag and Drop support
  •     Handling unsupported browser versions
  •     CSS3 makes its way into GWT
  •     Angry Birds / ForPlay




Thursday, June 30, 2011                         10
Local Storage
    Isn't it just a cookie?




Thursday, June 30, 2011       11
Local Storage
    Isn't it just a cookie?

  • Cookies are sent with each request!
  • Local storage provides MBs worth of storage
  • Local storage can be shared between browser windows




Thursday, June 30, 2011                                   12
Local Storage
    Available in GWT
  • GWT provides a Storage API

    Storage storage = Storage.getLocalStorageIfSupported();
    if (storage != null) {
      storage.setItem("foo", "bar");
    }




    Storage storage = Storage.getLocalStorageIfSupported();
    if (storage != null) {
      String value = storage.getItem("foo");
    }




Thursday, June 30, 2011                                       13
Local Storage
    Available in GWT
  • GWT provides a Storage API

    Storage storage = Storage.getLocalStorageIfSupported();
    if (storage != null) {
      storage.setItem("foo", "bar");
    }




    Storage storage = Storage.getLocalStorageIfSupported();
    if (storage != null) {
      String value = storage.getItem("foo");
    }




Thursday, June 30, 2011                                       14
Local Storage
    Available in GWT
  • GWT provides a Storage API

    Storage storage = Storage.getLocalStorageIfSupported();
    if (storage != null) {
      storage.setItem("foo", "bar");
    }




    Storage storage = Storage.getLocalStorageIfSupported();
    if (storage != null) {
      String value = storage.getItem("foo");
    }




Thursday, June 30, 2011                                       15
Local Storage
    Available in GWT
  • StorageMap lets you access storage using a java.util.Map
        o   Contributions by Bart Guijt


   Storage storage = Storage.getLocalStorageIfSupported();
   if (storage != null) {
     StorageMap map = new StorageMap(storage);
     storage.put("foo", "bar");
   }




Thursday, June 30, 2011                                        16
Local Storage
    For improved performance
  • Cache data from RPC calls
  • Load cached data on startup for faster startup times




Thursday, June 30, 2011                                    17
Local Storage
    For improved performance
  • Cache data from RPC calls
  • Load cached data on startup for faster startup times




Thursday, June 30, 2011                                    18
Local Storage
    For improved performance




                           Demo




Thursday, June 30, 2011           19
Local Storage
    For improved user experience

  • Save temporary state to local storage
  • Restore state when user re-enters app
  • Prevent lost work on network disconnect




Thursday, June 30, 2011                       20
Agenda

  •     Overview
  •     Local Storage for performance
  •     Visualizations via Canvas
  •     Enrich your app with Audio
  •     Embedding Video in your app
  •     Drag and Drop support
  •     Handling unsupported browser versions
  •     CSS3 makes its way into GWT
  •     Angry Birds / ForPlay




Thursday, June 30, 2011                         21
Canvas
    Adding visualizations to your app



                                        • This slide is boring

         Past Due            3
         Due Tomorrow        1
         On Time             1
         No Due Date         6




Thursday, June 30, 2011                                          22
Canvas
    Adding visualizations to your app



                                        • Charts bring data to life
                                        • Canvas brings charts to the web




Thursday, June 30, 2011                                                     23
Canvas
    Adding visualizations to your app




                                Demo




Thursday, June 30, 2011                 24
Canvas
    Adding visualizations to your app

     1. Initialize the canvas
     2. Calculate values for new shapes
     3. Clear the current canvas
     4. Draw the new shapes




Thursday, June 30, 2011                   25
    // Initialize the canvas.
    final Canvas canvas = Canvas.createIfSupported();
    canvas.setCoordinateSpaceHeight(300);
    canvas.setCoordinateSpaceWidth(300);
    canvas.setPixelSize(300, 300);
    // Get the dimensions of the canvas.
    int width = canvas.getCoordinateSpaceWidth();
    int height = canvas.getCoordinateSpaceHeight();
    double radius = Math.min(width, height) / 2.0;
    double cx = width / 2.0;
    double cy = height / 2.0;
    // Clear the context.
    Context2d context = canvas.getContext2d();
    context.clearRect(0, 0, width, height);
    // Draw a filled arc.
    context.setFillStyle(CssColor.make(255, 211, 25));
    context.beginPath();
    context.moveTo(cx, cy);
    context.arc(cx, cy, radius, 0, Math.PI);
    context.fill();




Thursday, June 30, 2011                                  26
    // Initialize the canvas.
    final Canvas canvas = Canvas.createIfSupported();
    canvas.setCoordinateSpaceHeight(300);
    canvas.setCoordinateSpaceWidth(300);
    canvas.setPixelSize(300, 300);
    // Get the dimensions of the canvas.
    int width = canvas.getCoordinateSpaceWidth();
    int height = canvas.getCoordinateSpaceHeight();
    double radius = Math.min(width, height) / 2.0;
    double cx = width / 2.0;
    double cy = height / 2.0;
    // Clear the context.
    Context2d context = canvas.getContext2d();
    context.clearRect(0, 0, width, height);
    // Draw a filled arc.
    context.setFillStyle(CssColor.make(255, 211, 25));
    context.beginPath();
    context.moveTo(cx, cy);
    context.arc(cx, cy, radius, 0, Math.PI);
    context.fill();




Thursday, June 30, 2011                                  27
    // Initialize the canvas.
    final Canvas canvas = Canvas.createIfSupported();
    canvas.setCoordinateSpaceHeight(300);
    canvas.setCoordinateSpaceWidth(300);
    canvas.setPixelSize(300, 300);
    // Get the dimensions of the canvas.
    int width = canvas.getCoordinateSpaceWidth();
    int height = canvas.getCoordinateSpaceHeight();
    double radius = Math.min(width, height) / 2.0;
    double cx = width / 2.0;
    double cy = height / 2.0;
    // Clear the context.
    Context2d context = canvas.getContext2d();
    context.clearRect(0, 0, width, height);
    // Draw a filled arc.
    context.setFillStyle(CssColor.make(255, 211, 25));
    context.beginPath();
    context.moveTo(cx, cy);
    context.arc(cx, cy, radius, 0, Math.PI);
    context.fill();




Thursday, June 30, 2011                                  28
    // Initialize the canvas.
    final Canvas canvas = Canvas.createIfSupported();
    canvas.setCoordinateSpaceHeight(300);
    canvas.setCoordinateSpaceWidth(300);
    canvas.setPixelSize(300, 300);
    // Get the dimensions of the canvas.
    int width = canvas.getCoordinateSpaceWidth();
    int height = canvas.getCoordinateSpaceHeight();
    double radius = Math.min(width, height) / 2.0;
    double cx = width / 2.0;
    double cy = height / 2.0;
    // Clear the context.
    Context2d context = canvas.getContext2d();
    context.clearRect(0, 0, width, height);
    // Draw a filled arc.
    context.setFillStyle(CssColor.make(255, 211, 25));
    context.beginPath();
    context.moveTo(cx, cy);
    context.arc(cx, cy, radius, 0, Math.PI);
    context.fill();




Thursday, June 30, 2011                                  29
Canvas
    Adding visualizations to your app

  • Canvas has a coordinate space separate from DOM size
  • Coordinate space is scaled to the DOM size
     o Small coordinate space = faster performance
     o Large coordinate space = higher quality
  • Match coordinate space to DOM size
     o Assign a fixed size to the DOM element, or
     o Catch resize events and adjust the coordinate space




                          300x300               30x30




Thursday, June 30, 2011                                      30
Agenda

  •     Overview
  •     Local Storage for performance
  •     Visualizations via Canvas
  •     Enrich your app with Audio
  •     Embedding Video in your app
  •     Drag and Drop support
  •     Handling unsupported browser versions
  •     CSS3 makes its way into GWT
  •     Angry Birds / ForPlay




Thursday, June 30, 2011                         31
Audio

  • Embed audio using the Audio widget
  • Play a sound or stream




Thursday, June 30, 2011                  32
Audio




                          Demo




Thursday, June 30, 2011          33
Audio

  • Format support varies across browsers
  • Choose at least two of the three main formats

                               Ogg Vorbis              MP3      WAV

            Chrome                  ✓                   ✓
            Firefox                 ✓                           ✓
            Internet
            Explorer                                    ✓       ✓
            Opera                   ✓                           ✓
            Safari                                      ✓       ✓
  Source: http://html5doctor.com/native-audio-in-the-browser/


Thursday, June 30, 2011                                               34
Audio
    Specify multiple sources

  • You can specify multiple sources in HTML5
  • Don't forget the "type" attribute
     o Browsers will load all source files
     o Must load meta data to detect mime-type
     o Cannot assume mime-type from file extension



   <audio controls>
     <source src="path/file.ogg" type="audio/ogg" />
     <source src="path/file.mp3" type="audio/mpeg" />
     <source src="path/file.wav" type="audio/wav" />
   </audio>




Thursday, June 30, 2011                                 35
Audio
    Specify multiple sources (2.4)
public Audio createAudio() {
  Audio audio = Audio.createIfSupported();
  if (audio == null) {
    return;
  }

     audio.addSource("path/file.ogg", AudioElement.TYPE_OGG);
     audio.addSource("path/file.mp3", AudioElement.TYPE_MP3);
     audio.addSource("path/file.wav", AudioElement.TYPE_WAV);

     // Show audio controls.
     audio.setControls(true);
     return audio;
}




Thursday, June 30, 2011                                         36
Audio
    Specify multiple sources (2.4)
public Audio createAudio() {
  Audio audio = Audio.createIfSupported();
  if (audio == null) {
    return;
  }

     audio.addSource("path/file.ogg", AudioElement.TYPE_OGG);
     audio.addSource("path/file.mp3", AudioElement.TYPE_MP3);
     audio.addSource("path/file.wav", AudioElement.TYPE_WAV);

     // Show audio controls.
     audio.setControls(true);
     return audio;
}




Thursday, June 30, 2011                                         37
Audio
    Specify multiple sources (2.4)
public Audio createAudio() {
  Audio audio = Audio.createIfSupported();
  if (audio == null) {
    return;
  }

     audio.addSource("path/file.ogg", AudioElement.TYPE_OGG);
     audio.addSource("path/file.mp3", AudioElement.TYPE_MP3);
     audio.addSource("path/file.wav", AudioElement.TYPE_WAV);

     // Show audio controls.
     audio.setControls(true);
     return audio;
}




Thursday, June 30, 2011                                         38
Audio
    Specify multiple sources (2.4)
public Audio createAudio() {
  Audio audio = Audio.createIfSupported();
  if (audio == null) {
    return;
  }

     audio.addSource("path/file.ogg", AudioElement.TYPE_OGG);
     audio.addSource("path/file.mp3", AudioElement.TYPE_MP3);
     audio.addSource("path/file.wav", AudioElement.TYPE_WAV);

     // Show audio controls.
     audio.setControls(true);
     return audio;
}




Thursday, June 30, 2011                                         39
Audio
    Manually choose the source
  • You can ask the browser which files it might support
     o Tells you "probably", "maybe", or ""
  • Ensures that you only load that source




Thursday, June 30, 2011                                    40
public Audio createAudio() {
         Audio audio = Audio.createIfSupported();
         if (audio == null) {
           return;
         }
         if (MediaElement.CAN_PLAY_PROBABLY.equals(
               audio.canPlayType(AudioElement.TYPE_OGG)) {
           audio.setSrc("path/file.ogg");
         } else if (MediaElement.CAN_PLAY_PROBABLY.equals(
               audio.canPlayType(AudioElement.TYPE_MP3)) {
           audio.setSrc("path/file.mp3");
         } else if (MediaElement.CAN_PLAY_MAYBE.equals(
               audio.canPlayType(AudioElement.TYPE_OGG)) {
           audio.setSrc("path/file.mp3");
         } else if (MediaElement.CAN_PLAY_MAYBE.equals(
               audio.canPlayType(AudioElement.TYPE_MP3)) {
           audio.setSrc("path/file.mp3");
         }
         return audio;
       }



Thursday, June 30, 2011                                      41
public Audio createAudio() {
        Audio audio = Audio.createIfSupported();
        if (audio == null) {
          return;
        }
        if (MediaElement.CAN_PLAY_PROBABLY.equals(
              audio.canPlayType(AudioElement.TYPE_OGG)) {
          audio.setSrc("path/file.ogg");
        } else if (MediaElement.CAN_PLAY_PROBABLY.equals(
              audio.canPlayType(AudioElement.TYPE_MP3)) {
          audio.setSrc("path/file.mp3");
        } else if (MediaElement.CAN_PLAY_MAYBE.equals(
              audio.canPlayType(AudioElement.TYPE_OGG)) {
          audio.setSrc("path/file.mp3");
        } else if (MediaElement.CAN_PLAY_MAYBE.equals(
              audio.canPlayType(AudioElement.TYPE_MP3)) {
          audio.setSrc("path/file.mp3");
        }
        return audio;
      }



Thursday, June 30, 2011                                     42
Audio
    Preloading a file
  • Let the browser decide when to preload

          Audio audio = Audio.createIfSupported();
          audio.setSrc("path/file.ogg");
          audio.setPreload(MediaElement.PRELOAD_AUTO);

  • Or force the browser to preload


          Audio audio = Audio.createIfSupported();
          audio.setSrc("path/file.ogg");
          audio.load();




Thursday, June 30, 2011                                  43
Audio
    Preloading a file
  • Let the browser decide when to preload

          Audio audio = Audio.createIfSupported();
          audio.setSrc("path/file.ogg");
          audio.setPreload(MediaElement.PRELOAD_AUTO);

  • Or force the browser to preload


          Audio audio = Audio.createIfSupported();
          audio.setSrc("path/file.ogg");
          audio.load();




Thursday, June 30, 2011                                  44
Audio
    Preloading a file
  • Let the browser decide when to preload

          Audio audio = Audio.createIfSupported();
          audio.setSrc("path/file.ogg");
          audio.setPreload(MediaElement.PRELOAD_AUTO);

  • Or force the browser to preload


          Audio audio = Audio.createIfSupported();
          audio.setSrc("path/file.ogg");
          audio.load();




Thursday, June 30, 2011                                  45
Agenda

  •     Overview
  •     Local Storage for performance
  •     Visualizations via Canvas
  •     Enrich your app with Audio
  •     Embedding Video in your app
  •     Drag and Drop support
  •     Handling unsupported browser versions
  •     CSS3 makes its way into GWT
  •     Angry Birds / ForPlay




Thursday, June 30, 2011                         46
Video

  • Embed videos using the Video widget
  • Play a static video or a stream




Thursday, June 30, 2011                   47
Video




                          Demo




Thursday, June 30, 2011          48
Video

  • Format support varies across browsers
  • Choose at least two of the three main formats
     o Safari only supports mp4


                                Ogg Vorbis           MP4   WebM

               Chrome                ✓                      ✓
               Firefox               ✓                      ✓
               Internet
               Explorer                              ✓
               Opera                 ✓                      ✓
               Safari                                ✓
  Source: http://en.wikipedia.org/wiki/HTML5_video

Thursday, June 30, 2011                                           49
Video
public Video createVideo() {
  Video video = Video.createIfSupported();
  if (video == null) {
    return null;
 }

  video.addSource("path/file.ogg", VideoElement.TYPE_OGG);
  video.addSource("path/file.mp4", VideoElement.TYPE_MP4);
  video.addSource("path/file.webm", VideoElement.TYPE_WEBM);

  // Show audio controls.
  video.setControls(true);
  return video;
}




Thursday, June 30, 2011                                       50
Video
public Video createVideo() {
  Video video = Video.createIfSupported();
  if (video == null) {
    return null;
 }

  video.addSource("path/file.ogg", VideoElement.TYPE_OGG);
  video.addSource("path/file.mp4", VideoElement.TYPE_MP4);
  video.addSource("path/file.webm", VideoElement.TYPE_WEBM);

  // Show audio controls.
  video.setControls(true);
  return video;
}




Thursday, June 30, 2011                                       51
Video
public Video createVideo() {
  Video video = Video.createIfSupported();
  if (video == null) {
    return null;
 }

  video.addSource("path/file.ogg", VideoElement.TYPE_OGG);
  video.addSource("path/file.mp4", VideoElement.TYPE_MP4);
  video.addSource("path/file.webm", VideoElement.TYPE_WEBM);

  // Show audio controls.
  video.setControls(true);
  return video;
}




Thursday, June 30, 2011                                       52
Video
public Video createVideo() {
  Video video = Video.createIfSupported();
  if (video == null) {
    return null;
 }

  video.addSource("path/file.ogg", VideoElement.TYPE_OGG);
  video.addSource("path/file.mp4", VideoElement.TYPE_MP4);
  video.addSource("path/file.webm", VideoElement.TYPE_WEBM);

  // Show audio controls.
  video.setControls(true);
  return video;
}




Thursday, June 30, 2011                                       53
Agenda

  •     Overview
  •     Local Storage for performance
  •     Visualizations via Canvas
  •     Enrich your app with Audio
  •     Embedding Video in your app
  •     Drag and Drop support
  •     Handling unsupported browser versions
  •     CSS3 makes its way into GWT
  •     Angry Birds / ForPlay




Thursday, June 30, 2011                         54
Drag and Drop

  • Move stuff around... with style
  • Associate text or ID with the event
  • Many types of drag events




Thursday, June 30, 2011                   55
Drag and Drop




                          Demo




Thursday, June 30, 2011          56
Drag and Drop
    Make a widget draggable
     • Set the "draggable" attribute to "true"
     • Add a DragStart handler
     • Set data in the DragStart handler




Thursday, June 30, 2011                          57
Drag and Drop
    Make a widget draggable
   // Make the widget draggable.
   Label w = new Label("Drag Me");
   w.getElement().setDraggable(Element.DRAGGABLE_TRUE);

   // Add a DragStartHandler.
   w.addDragStartHandler(new DragStartHandler() {
     public void onDragStart(DragStartEvent event) {
       // Required: set data for the event.
       event.setData("text", "Hello World");

       // Optional: show a copy of the widget under cursor.
       event.getDataTransfer().setDragImage(w.getElement(),
           10, 10);
    }
   });




Thursday, June 30, 2011                                       58
Drag and Drop
    Make a widget draggable
   // Make the widget draggable.
   Label w = new Label("Drag Me");
   w.getElement().setDraggable(Element.DRAGGABLE_TRUE);

   // Add a DragStartHandler.
   w.addDragStartHandler(new DragStartHandler() {
     public void onDragStart(DragStartEvent event) {
       // Required: set data for the event.
       event.setData("text", "Hello World");

       // Optional: show a copy of the widget under cursor.
       event.getDataTransfer().setDragImage(w.getElement(),
           10, 10);
    }
   });




Thursday, June 30, 2011                                       59
Drag and Drop
    Make a widget draggable
   // Make the widget draggable.
   Label w = new Label("Drag Me");
   w.getElement().setDraggable(Element.DRAGGABLE_TRUE);

   // Add a DragStartHandler.
   w.addDragStartHandler(new DragStartHandler() {
     public void onDragStart(DragStartEvent event) {
       // Required: set data for the event.
       event.setData("text", "Hello World");

       // Optional: show a copy of the widget under cursor.
       event.getDataTransfer().setDragImage(w.getElement(),
           10, 10);
    }
   });




Thursday, June 30, 2011                                       60
Drag and Drop
    Make a widget draggable
   // Make the widget draggable.
   Label w = new Label("Drag Me");
   w.getElement().setDraggable(Element.DRAGGABLE_TRUE);

   // Add a DragStartHandler.
   w.addDragStartHandler(new DragStartHandler() {
     public void onDragStart(DragStartEvent event) {
       // Required: set data for the event.
       event.setData("text", "Hello World");

       // Optional: show a copy of the widget under cursor.
       event.getDataTransfer().setDragImage(w.getElement(),
           10, 10);
    }
   });




Thursday, June 30, 2011                                       61
Drag and Drop
    Make a widget draggable
   // Make the widget draggable.
   Label w = new Label("Drag Me");
   w.getElement().setDraggable(Element.DRAGGABLE_TRUE);

   // Add a DragStartHandler.
   w.addDragStartHandler(new DragStartHandler() {
     public void onDragStart(DragStartEvent event) {
       // Required: set data for the event.
       event.setData("text", "Hello World");

       // Optional: show a copy of the widget under cursor.
       event.getDataTransfer().setDragImage(w.getElement(),
           10, 10);
    }
   });




Thursday, June 30, 2011                                       62
Drag and Drop
    Create a target
     • Add a DragOver handler
     • Add a Drop handler
        o Prevent default action
        o Get the data from the transfer object




Thursday, June 30, 2011                           63
Label target = new Label("Drag onto me");

      // Required: You must add a DragOverHandler to
      // create a target.
      target.addDragOverHandler(new DragOverHandler() {
        public void onDragOver(DragOverEvent event) {
          target.getElement().setBackgroundColor("#ffa");
        }
      });

      // Add a DropHandler.
      target.addDropHandler(new DropHandler() {
        public void onDrop(DropEvent event) {
          // Prevent the native text drop.
          event.preventDefault();

              // Get the data out of the event.
              String data = event.getData("text");
              target.setText(data);
        }
      });




Thursday, June 30, 2011                                     64
Label target = new Label("Drag onto me");

      // Required: You must add a DragOverHandler to
      // create a target.
      target.addDragOverHandler(new DragOverHandler() {
        public void onDragOver(DragOverEvent event) {
          target.getElement().setBackgroundColor("#ffa");
        }
      });

      // Add a DropHandler.
      target.addDropHandler(new DropHandler() {
        public void onDrop(DropEvent event) {
          // Prevent the native text drop.
          event.preventDefault();

              // Get the data out of the event.
              String data = event.getData("text");
              target.setText(data);
        }
      });




Thursday, June 30, 2011                                     65
Label target = new Label("Drag onto me");

      // Required: You must add a DragOverHandler to
      // create a target.
      target.addDragOverHandler(new DragOverHandler() {
        public void onDragOver(DragOverEvent event) {
          target.getElement().setBackgroundColor("#ffa");
        }
      });

      // Add a DropHandler.
      target.addDropHandler(new DropHandler() {
        public void onDrop(DropEvent event) {
          // Prevent the native text drop.
          event.preventDefault();

              // Get the data out of the event.
              String data = event.getData("text");
              target.setText(data);
        }
      });




Thursday, June 30, 2011                                     66
Label target = new Label("Drag onto me");

      // Required: You must add a DragOverHandler to
      // create a target.
      target.addDragOverHandler(new DragOverHandler() {
        public void onDragOver(DragOverEvent event) {
          target.getElement().setBackgroundColor("#ffa");
        }
      });

      // Add a DropHandler.
      target.addDropHandler(new DropHandler() {
        public void onDrop(DropEvent event) {
          // Prevent the native text drop.
          event.preventDefault();

              // Get the data out of the event.
              String data = event.getData("text");
              target.setText(data);
        }
      });




Thursday, June 30, 2011                                     67
Label target = new Label("Drag onto me");

      // Required: You must add a DragOverHandler to
      // create a target.
      target.addDragOverHandler(new DragOverHandler() {
        public void onDragOver(DragOverEvent event) {
          target.getElement().setBackgroundColor("#ffa");
        }
      });

      // Add a DropHandler.
      target.addDropHandler(new DropHandler() {
        public void onDrop(DropEvent event) {
          // Prevent the native text drop.
          event.preventDefault();

              // Get the data out of the event.
              String data = event.getData("text");
              target.setText(data);
        }
      });




Thursday, June 30, 2011                                     68
Drag and Drop
    On any widget
       • Some widgets do not implement drag handlers
       • You can always use addDomHandler() to add a handler

    // Add a DragStartHandler.
    w.addDomHandler(new DragStartHandler() {
      public void onDragStart(DragStartEvent event) {
        // Required: set data for the event.
        event.setData("text", "Hello World");

        // Optional: show a copy of the widget under cursor.
        event.getDataTransfer().setDragImage(w.getElement,
             10, 10);
     }
    }, DragStartEvent.getType());




Thursday, June 30, 2011                                        69
Drag and Drop
    + File API?
        • Spec is still changing rapidly.
        • Not in GWT (yet!)

      File[] files = event.getDataTransfer().getFiles();

      // read an entire file
      String txt = FileReader.readAsBinaryString(files[0]);

        // read a chunk of a file
        Reader reader = new Reader();
        Blob blob = files[0].slice(startingByte, length);
        String txt = reader.readAsBinaryString(blob);




Thursday, June 30, 2011                                      70
Drag and Drop Uploader




                          Demo




Thursday, June 30, 2011          71
Agenda

  •     Overview
  •     Local Storage for performance
  •     Visualizations via Canvas
  •     Enrich your app with Audio
  •     Embedding Video in your app
  •     Drag and Drop support
  •     Handling unsupported browser versions
  •     CSS3 makes its way into GWT
  •     Angry Birds / ForPlay




Thursday, June 30, 2011                         72
Partial Support
    Because if all browsers supported it, it would be too easy

  • GWT provides APIs that are not supported in all browsers
     o Modern browsers gaining market share rapidly
  • Implementors of PartialSupport provide two static methods:
     o isSupported()
     o createIfSupported()
          "Compiles out" if on a non-supported permutation!




Thursday, June 30, 2011                                          73
Partial Support
    Fallback to another implementation
    public void showChart(AcceptsOneWidget panel,
        ChartData data) {
      Canvas canvas = Canvas.createIfSupported();
      if (canvas == null) {
        // Fallback to an image if Canvas isn't supported.
        String imageUrl = encodeChartData(data);
        panel.setWidget(new Image(imageUrl);
        return;
     }

      // Create a canvas chart.
      ...

      // Display the canvas.
      panel.setWidget(canvas);
    }




Thursday, June 30, 2011                                      74
Agenda

  •     Overview
  •     Local Storage for performance
  •     Visualizations via Canvas
  •     Enrich your app with Audio
  •     Embedding Video in your app
  •     Drag and Drop support
  •     Handling unsupported browser versions
  •     CSS3 makes its way into GWT
  •     Angry Birds / ForPlay




Thursday, June 30, 2011                         75
CSS3
    Style your GWT app

  • Nothing special required for CSS3
     o Rounded corners, drop shadows, animations, group opacity,
       multiple backgrounds, 3D transforms, etc.
     o No changes required for GWT's UIBinder




Thursday, June 30, 2011                                            76
CSS3 in GWT's Widgets
  • As of GWT 2.3, widgets now use CSS3
  • On legacy browsers, widgets will be "usable"


                          Example: Rounded Corners




Thursday, June 30, 2011                              77
Agenda

  •     Overview
  •     Local Storage for performance
  •     Visualizations via Canvas
  •     Enrich your app with Audio
  •     Embedding Video in your app
  •     Drag and Drop support
  •     Handling unsupported browser versions
  •     CSS3 makes its way into GWT
  •     Angry Birds / ForPlay




Thursday, June 30, 2011                         78
Angry Birds / ForPlay




                            Demo




Thursday, June 30, 2011            79
Angry Birds
    An HTML5 GWT app

  • Announced at Google IO 2011
  • Built with a library called ForPlay
    o Uses GWT for Java -> HTML5 step.
  • Uses most of the technologies talked about here
    o Canvas, Audio*, Storage, CSS3
    o Prove it




Thursday, June 30, 2011                               80
Angry Birds
    An HTML5 GWT app

  • Announced at Google IO 2011
  • Built with a library called ForPlay
    o Uses GWT for Java -> HTML5 step.
  • Uses most of the technologies talked about here
    o Canvas, Audio*, Storage, CSS3
    o Prove it



  • Check out the I/O talk:
    Kick-Ass Game Programming
    with Google Web Toolkit
  • http://goo.gl/UZ4X4



Thursday, June 30, 2011                               81
ForPlay
    In 30 seconds

  • Cross-platform library for games
     o Cross-browser (HTML5): WebGL, Canvas, 3D CSS
     o Android, Flash, and Java apps too
  • Write and debug games using the ForPlay API, compile
    onto many platforms.
  • API includes cross-platform abstractions for startup,
    asset management, input (keyboard, touch, mouse),
    audio, graphics, physics engine (box2d), json parsing,
    etc.




Thursday, June 30, 2011                                      82
ForPlay
    An GWT library for games

  • Some demos
    o Joel Webber's XNA Platormer port
    o Aquarium by Mohamed Ousgougou / SFEIR
    o http://p4cdroid.appspot.com/
    o more examples, including source at gwtforplay.com

  • For more info or if you'd like to join in:
                 http://gwtforplay.com




Thursday, June 30, 2011                                   83
GWT + HTML5
    GTUG Atlanta
    David Chandler drfibonacci@google.com
    Philip Rogers pdr@google.com




Thursday, June 30, 2011                     84

More Related Content

Similar to GWT Plus HTML 5 (20)

PDF
Elements2011 html5-app-110928141627-phpapp01
Jesse Smith
 
PDF
Desingning reusable web components
Joonas Lehtinen
 
PDF
Alejandro Villanueva - Google Inc.
Alejandro Corpeño
 
PDF
Google - Charla para CTOs
Palermo Valley
 
PDF
GWT Overview And Feature Preview - SV Web JUG - June 16 2009
Fred Sauer
 
PDF
Google's HTML5 Work: what's next?
Patrick Chanezon
 
PDF
The Enterprise Dilemma: Native vs. Web
Motorola Mobility - MOTODEV
 
PPTX
HTML5 for Rich User Experience
Mahbubur Rahman
 
PDF
Get Ahead with HTML5 on Moible
markuskobler
 
PDF
HTML5 and Google Chrome - DevFest09
mihaiionescu
 
PPTX
HTML5 on Mobile
Adam Lu
 
PDF
Is HTML5 Ready? (workshop)
Remy Sharp
 
PDF
Is html5-ready-workshop-110727181512-phpapp02
PL dream
 
PDF
Google Developer Days Brazil 2009 - Keynote
Patrick Chanezon
 
PDF
WebSphere User Group UK: Larger Applications with Worklight
Andrew Ferrier
 
PPTX
Graphical display of statistical data on Android
Didac Montero
 
PDF
Mobile Web Development with HTML5
Roy Clarkson
 
ZIP
Mobile HTML5
Pascal Rettig
 
PDF
Html5 with Vaadin and Scala
Joonas Lehtinen
 
PPTX
HTML5 - Chances and Pitfalls (Bytro Labs GmbH)
Felix Faber
 
Elements2011 html5-app-110928141627-phpapp01
Jesse Smith
 
Desingning reusable web components
Joonas Lehtinen
 
Alejandro Villanueva - Google Inc.
Alejandro Corpeño
 
Google - Charla para CTOs
Palermo Valley
 
GWT Overview And Feature Preview - SV Web JUG - June 16 2009
Fred Sauer
 
Google's HTML5 Work: what's next?
Patrick Chanezon
 
The Enterprise Dilemma: Native vs. Web
Motorola Mobility - MOTODEV
 
HTML5 for Rich User Experience
Mahbubur Rahman
 
Get Ahead with HTML5 on Moible
markuskobler
 
HTML5 and Google Chrome - DevFest09
mihaiionescu
 
HTML5 on Mobile
Adam Lu
 
Is HTML5 Ready? (workshop)
Remy Sharp
 
Is html5-ready-workshop-110727181512-phpapp02
PL dream
 
Google Developer Days Brazil 2009 - Keynote
Patrick Chanezon
 
WebSphere User Group UK: Larger Applications with Worklight
Andrew Ferrier
 
Graphical display of statistical data on Android
Didac Montero
 
Mobile Web Development with HTML5
Roy Clarkson
 
Mobile HTML5
Pascal Rettig
 
Html5 with Vaadin and Scala
Joonas Lehtinen
 
HTML5 - Chances and Pitfalls (Bytro Labs GmbH)
Felix Faber
 

More from David Chandler (13)

PPTX
Taking Your GWT App to Tablets with GXT 4.0
David Chandler
 
PDF
StORM: a lightweight ORM for Android SQLite
David Chandler
 
PDF
Easy REST APIs with Jersey and RestyGWT
David Chandler
 
PDF
Cómo trabajan los Googlers
David Chandler
 
PDF
Life of an engineer
David Chandler
 
PDF
Google App Engine Update 2012
David Chandler
 
PDF
Scalable Apps with Google App Engine
David Chandler
 
PDF
What's New in GWT 2.2
David Chandler
 
PDF
Develop and Deploy Scalable Apps with Google App Engine
David Chandler
 
PDF
Secrets of the GWT
David Chandler
 
PPT
The 90-Day Startup with Google AppEngine for Java
David Chandler
 
PPT
GWT MVP Case Study
David Chandler
 
PDF
Securing JSF Applications Against the OWASP Top Ten
David Chandler
 
Taking Your GWT App to Tablets with GXT 4.0
David Chandler
 
StORM: a lightweight ORM for Android SQLite
David Chandler
 
Easy REST APIs with Jersey and RestyGWT
David Chandler
 
Cómo trabajan los Googlers
David Chandler
 
Life of an engineer
David Chandler
 
Google App Engine Update 2012
David Chandler
 
Scalable Apps with Google App Engine
David Chandler
 
What's New in GWT 2.2
David Chandler
 
Develop and Deploy Scalable Apps with Google App Engine
David Chandler
 
Secrets of the GWT
David Chandler
 
The 90-Day Startup with Google AppEngine for Java
David Chandler
 
GWT MVP Case Study
David Chandler
 
Securing JSF Applications Against the OWASP Top Ten
David Chandler
 
Ad

Recently uploaded (20)

PPTX
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 
PDF
HubSpot Main Hub: A Unified Growth Platform
Jaswinder Singh
 
PDF
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
PPTX
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
PDF
Complete JavaScript Notes: From Basics to Advanced Concepts.pdf
haydendavispro
 
PPTX
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
PDF
DevBcn - Building 10x Organizations Using Modern Productivity Metrics
Justin Reock
 
PDF
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
PDF
Smart Trailers 2025 Update with History and Overview
Paul Menig
 
PDF
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
PDF
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
PPTX
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
PDF
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
PPTX
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
PDF
How Startups Are Growing Faster with App Developers in Australia.pdf
India App Developer
 
PPTX
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
PDF
July Patch Tuesday
Ivanti
 
PDF
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
PPTX
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
Fwdays
 
PPTX
UiPath Academic Alliance Educator Panels: Session 2 - Business Analyst Content
DianaGray10
 
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 
HubSpot Main Hub: A Unified Growth Platform
Jaswinder Singh
 
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
Complete JavaScript Notes: From Basics to Advanced Concepts.pdf
haydendavispro
 
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
DevBcn - Building 10x Organizations Using Modern Productivity Metrics
Justin Reock
 
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
Smart Trailers 2025 Update with History and Overview
Paul Menig
 
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
How Startups Are Growing Faster with App Developers in Australia.pdf
India App Developer
 
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
July Patch Tuesday
Ivanti
 
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
Fwdays
 
UiPath Academic Alliance Educator Panels: Session 2 - Business Analyst Content
DianaGray10
 
Ad

GWT Plus HTML 5

  • 1. GWT + HTML5 GTUG Atlanta David Chandler [email protected] Philip Rogers [email protected] Thursday, June 30, 2011 1
  • 2. Agenda • Overview • Local Storage for performance • Visualizations via Canvas • Enrich your app with Audio • Embedding Video in your app • Drag and Drop support • Handling unsupported browser versions • CSS3 makes its way into GWT • Angry Birds / ForPlay Thursday, June 30, 2011 2
  • 3. Overview • What to expect o Lots of demos o Lots of code examples • What you will learn o How to use HTML5 in your GWT app Thursday, June 30, 2011 3
  • 4. Overview What is HTML5? • HTML5 includes lots of stuff o Media rich DOM elements o Useful new APIs o CSS3 enhancements • Support is increasing very rapidly • Embrace it to make your apps stand out Thursday, June 30, 2011 4
  • 6. Why now? Hint: Thursday, June 30, 2011 6
  • 7. HTML5 for Designers header,nav,footer -- more semantic meaning aside concept HSL color @font-face border-radius transforms, transitions Canvas HTML5 video player (sans Flash) Thursday, June 30, 2011 7
  • 8. HTML5 for Programmers • WebSockets • Client-side storage o LocalStorage API o Web SQL (it's dead, Jim) o indexedDB • Web Workers • form fields o type=email,date,range,search,tel,color,... • <meter>,<progress> • app cache • notifications • geolocation • device orientation • server side events Thursday, June 30, 2011 8
  • 9. HTML5 support http://www.html5rocks.com/ http://html5test.com Thursday, June 30, 2011 9
  • 10. Agenda • Overview • Local Storage for performance • Visualizations via Canvas • Enrich your app with Audio • Embedding Video in your app • Drag and Drop support • Handling unsupported browser versions • CSS3 makes its way into GWT • Angry Birds / ForPlay Thursday, June 30, 2011 10
  • 11. Local Storage Isn't it just a cookie? Thursday, June 30, 2011 11
  • 12. Local Storage Isn't it just a cookie? • Cookies are sent with each request! • Local storage provides MBs worth of storage • Local storage can be shared between browser windows Thursday, June 30, 2011 12
  • 13. Local Storage Available in GWT • GWT provides a Storage API Storage storage = Storage.getLocalStorageIfSupported(); if (storage != null) {   storage.setItem("foo", "bar"); } Storage storage = Storage.getLocalStorageIfSupported(); if (storage != null) {   String value = storage.getItem("foo"); } Thursday, June 30, 2011 13
  • 14. Local Storage Available in GWT • GWT provides a Storage API Storage storage = Storage.getLocalStorageIfSupported(); if (storage != null) {   storage.setItem("foo", "bar"); } Storage storage = Storage.getLocalStorageIfSupported(); if (storage != null) {   String value = storage.getItem("foo"); } Thursday, June 30, 2011 14
  • 15. Local Storage Available in GWT • GWT provides a Storage API Storage storage = Storage.getLocalStorageIfSupported(); if (storage != null) {   storage.setItem("foo", "bar"); } Storage storage = Storage.getLocalStorageIfSupported(); if (storage != null) {   String value = storage.getItem("foo"); } Thursday, June 30, 2011 15
  • 16. Local Storage Available in GWT • StorageMap lets you access storage using a java.util.Map o Contributions by Bart Guijt Storage storage = Storage.getLocalStorageIfSupported(); if (storage != null) {   StorageMap map = new StorageMap(storage);   storage.put("foo", "bar"); } Thursday, June 30, 2011 16
  • 17. Local Storage For improved performance • Cache data from RPC calls • Load cached data on startup for faster startup times Thursday, June 30, 2011 17
  • 18. Local Storage For improved performance • Cache data from RPC calls • Load cached data on startup for faster startup times Thursday, June 30, 2011 18
  • 19. Local Storage For improved performance Demo Thursday, June 30, 2011 19
  • 20. Local Storage For improved user experience • Save temporary state to local storage • Restore state when user re-enters app • Prevent lost work on network disconnect Thursday, June 30, 2011 20
  • 21. Agenda • Overview • Local Storage for performance • Visualizations via Canvas • Enrich your app with Audio • Embedding Video in your app • Drag and Drop support • Handling unsupported browser versions • CSS3 makes its way into GWT • Angry Birds / ForPlay Thursday, June 30, 2011 21
  • 22. Canvas Adding visualizations to your app • This slide is boring Past Due 3 Due Tomorrow 1 On Time 1 No Due Date 6 Thursday, June 30, 2011 22
  • 23. Canvas Adding visualizations to your app • Charts bring data to life • Canvas brings charts to the web Thursday, June 30, 2011 23
  • 24. Canvas Adding visualizations to your app Demo Thursday, June 30, 2011 24
  • 25. Canvas Adding visualizations to your app 1. Initialize the canvas 2. Calculate values for new shapes 3. Clear the current canvas 4. Draw the new shapes Thursday, June 30, 2011 25
  • 26.   // Initialize the canvas.   final Canvas canvas = Canvas.createIfSupported();   canvas.setCoordinateSpaceHeight(300);   canvas.setCoordinateSpaceWidth(300);   canvas.setPixelSize(300, 300);   // Get the dimensions of the canvas.   int width = canvas.getCoordinateSpaceWidth();   int height = canvas.getCoordinateSpaceHeight();   double radius = Math.min(width, height) / 2.0;   double cx = width / 2.0;   double cy = height / 2.0;   // Clear the context.   Context2d context = canvas.getContext2d();   context.clearRect(0, 0, width, height);   // Draw a filled arc.   context.setFillStyle(CssColor.make(255, 211, 25));   context.beginPath();   context.moveTo(cx, cy);   context.arc(cx, cy, radius, 0, Math.PI);   context.fill(); Thursday, June 30, 2011 26
  • 27.   // Initialize the canvas.   final Canvas canvas = Canvas.createIfSupported();   canvas.setCoordinateSpaceHeight(300);   canvas.setCoordinateSpaceWidth(300);   canvas.setPixelSize(300, 300);   // Get the dimensions of the canvas.   int width = canvas.getCoordinateSpaceWidth();   int height = canvas.getCoordinateSpaceHeight();   double radius = Math.min(width, height) / 2.0;   double cx = width / 2.0;   double cy = height / 2.0;   // Clear the context.   Context2d context = canvas.getContext2d();   context.clearRect(0, 0, width, height);   // Draw a filled arc.   context.setFillStyle(CssColor.make(255, 211, 25));   context.beginPath();   context.moveTo(cx, cy);   context.arc(cx, cy, radius, 0, Math.PI);   context.fill(); Thursday, June 30, 2011 27
  • 28.   // Initialize the canvas.   final Canvas canvas = Canvas.createIfSupported();   canvas.setCoordinateSpaceHeight(300);   canvas.setCoordinateSpaceWidth(300);   canvas.setPixelSize(300, 300);   // Get the dimensions of the canvas.   int width = canvas.getCoordinateSpaceWidth();   int height = canvas.getCoordinateSpaceHeight();   double radius = Math.min(width, height) / 2.0;   double cx = width / 2.0;   double cy = height / 2.0;   // Clear the context.   Context2d context = canvas.getContext2d();   context.clearRect(0, 0, width, height);   // Draw a filled arc.   context.setFillStyle(CssColor.make(255, 211, 25));   context.beginPath();   context.moveTo(cx, cy);   context.arc(cx, cy, radius, 0, Math.PI);   context.fill(); Thursday, June 30, 2011 28
  • 29.   // Initialize the canvas.   final Canvas canvas = Canvas.createIfSupported();   canvas.setCoordinateSpaceHeight(300);   canvas.setCoordinateSpaceWidth(300);   canvas.setPixelSize(300, 300);   // Get the dimensions of the canvas.   int width = canvas.getCoordinateSpaceWidth();   int height = canvas.getCoordinateSpaceHeight();   double radius = Math.min(width, height) / 2.0;   double cx = width / 2.0;   double cy = height / 2.0;   // Clear the context.   Context2d context = canvas.getContext2d();   context.clearRect(0, 0, width, height);   // Draw a filled arc.   context.setFillStyle(CssColor.make(255, 211, 25));   context.beginPath();   context.moveTo(cx, cy);   context.arc(cx, cy, radius, 0, Math.PI);   context.fill(); Thursday, June 30, 2011 29
  • 30. Canvas Adding visualizations to your app • Canvas has a coordinate space separate from DOM size • Coordinate space is scaled to the DOM size o Small coordinate space = faster performance o Large coordinate space = higher quality • Match coordinate space to DOM size o Assign a fixed size to the DOM element, or o Catch resize events and adjust the coordinate space 300x300 30x30 Thursday, June 30, 2011 30
  • 31. Agenda • Overview • Local Storage for performance • Visualizations via Canvas • Enrich your app with Audio • Embedding Video in your app • Drag and Drop support • Handling unsupported browser versions • CSS3 makes its way into GWT • Angry Birds / ForPlay Thursday, June 30, 2011 31
  • 32. Audio • Embed audio using the Audio widget • Play a sound or stream Thursday, June 30, 2011 32
  • 33. Audio Demo Thursday, June 30, 2011 33
  • 34. Audio • Format support varies across browsers • Choose at least two of the three main formats Ogg Vorbis MP3 WAV Chrome ✓ ✓ Firefox ✓ ✓ Internet Explorer ✓ ✓ Opera ✓ ✓ Safari ✓ ✓ Source: http://html5doctor.com/native-audio-in-the-browser/ Thursday, June 30, 2011 34
  • 35. Audio Specify multiple sources • You can specify multiple sources in HTML5 • Don't forget the "type" attribute o Browsers will load all source files o Must load meta data to detect mime-type o Cannot assume mime-type from file extension <audio controls> <source src="path/file.ogg" type="audio/ogg" /> <source src="path/file.mp3" type="audio/mpeg" /> <source src="path/file.wav" type="audio/wav" /> </audio> Thursday, June 30, 2011 35
  • 36. Audio Specify multiple sources (2.4) public Audio createAudio() { Audio audio = Audio.createIfSupported(); if (audio == null) { return; } audio.addSource("path/file.ogg", AudioElement.TYPE_OGG); audio.addSource("path/file.mp3", AudioElement.TYPE_MP3); audio.addSource("path/file.wav", AudioElement.TYPE_WAV); // Show audio controls. audio.setControls(true); return audio; } Thursday, June 30, 2011 36
  • 37. Audio Specify multiple sources (2.4) public Audio createAudio() { Audio audio = Audio.createIfSupported(); if (audio == null) { return; } audio.addSource("path/file.ogg", AudioElement.TYPE_OGG); audio.addSource("path/file.mp3", AudioElement.TYPE_MP3); audio.addSource("path/file.wav", AudioElement.TYPE_WAV); // Show audio controls. audio.setControls(true); return audio; } Thursday, June 30, 2011 37
  • 38. Audio Specify multiple sources (2.4) public Audio createAudio() { Audio audio = Audio.createIfSupported(); if (audio == null) { return; } audio.addSource("path/file.ogg", AudioElement.TYPE_OGG); audio.addSource("path/file.mp3", AudioElement.TYPE_MP3); audio.addSource("path/file.wav", AudioElement.TYPE_WAV); // Show audio controls. audio.setControls(true); return audio; } Thursday, June 30, 2011 38
  • 39. Audio Specify multiple sources (2.4) public Audio createAudio() { Audio audio = Audio.createIfSupported(); if (audio == null) { return; } audio.addSource("path/file.ogg", AudioElement.TYPE_OGG); audio.addSource("path/file.mp3", AudioElement.TYPE_MP3); audio.addSource("path/file.wav", AudioElement.TYPE_WAV); // Show audio controls. audio.setControls(true); return audio; } Thursday, June 30, 2011 39
  • 40. Audio Manually choose the source • You can ask the browser which files it might support o Tells you "probably", "maybe", or "" • Ensures that you only load that source Thursday, June 30, 2011 40
  • 41. public Audio createAudio() { Audio audio = Audio.createIfSupported(); if (audio == null) { return; } if (MediaElement.CAN_PLAY_PROBABLY.equals( audio.canPlayType(AudioElement.TYPE_OGG)) { audio.setSrc("path/file.ogg"); } else if (MediaElement.CAN_PLAY_PROBABLY.equals( audio.canPlayType(AudioElement.TYPE_MP3)) { audio.setSrc("path/file.mp3"); } else if (MediaElement.CAN_PLAY_MAYBE.equals( audio.canPlayType(AudioElement.TYPE_OGG)) { audio.setSrc("path/file.mp3"); } else if (MediaElement.CAN_PLAY_MAYBE.equals( audio.canPlayType(AudioElement.TYPE_MP3)) { audio.setSrc("path/file.mp3"); } return audio; } Thursday, June 30, 2011 41
  • 42. public Audio createAudio() { Audio audio = Audio.createIfSupported(); if (audio == null) { return; } if (MediaElement.CAN_PLAY_PROBABLY.equals( audio.canPlayType(AudioElement.TYPE_OGG)) { audio.setSrc("path/file.ogg"); } else if (MediaElement.CAN_PLAY_PROBABLY.equals( audio.canPlayType(AudioElement.TYPE_MP3)) { audio.setSrc("path/file.mp3"); } else if (MediaElement.CAN_PLAY_MAYBE.equals( audio.canPlayType(AudioElement.TYPE_OGG)) { audio.setSrc("path/file.mp3"); } else if (MediaElement.CAN_PLAY_MAYBE.equals( audio.canPlayType(AudioElement.TYPE_MP3)) { audio.setSrc("path/file.mp3"); } return audio; } Thursday, June 30, 2011 42
  • 43. Audio Preloading a file • Let the browser decide when to preload Audio audio = Audio.createIfSupported(); audio.setSrc("path/file.ogg"); audio.setPreload(MediaElement.PRELOAD_AUTO); • Or force the browser to preload Audio audio = Audio.createIfSupported(); audio.setSrc("path/file.ogg"); audio.load(); Thursday, June 30, 2011 43
  • 44. Audio Preloading a file • Let the browser decide when to preload Audio audio = Audio.createIfSupported(); audio.setSrc("path/file.ogg"); audio.setPreload(MediaElement.PRELOAD_AUTO); • Or force the browser to preload Audio audio = Audio.createIfSupported(); audio.setSrc("path/file.ogg"); audio.load(); Thursday, June 30, 2011 44
  • 45. Audio Preloading a file • Let the browser decide when to preload Audio audio = Audio.createIfSupported(); audio.setSrc("path/file.ogg"); audio.setPreload(MediaElement.PRELOAD_AUTO); • Or force the browser to preload Audio audio = Audio.createIfSupported(); audio.setSrc("path/file.ogg"); audio.load(); Thursday, June 30, 2011 45
  • 46. Agenda • Overview • Local Storage for performance • Visualizations via Canvas • Enrich your app with Audio • Embedding Video in your app • Drag and Drop support • Handling unsupported browser versions • CSS3 makes its way into GWT • Angry Birds / ForPlay Thursday, June 30, 2011 46
  • 47. Video • Embed videos using the Video widget • Play a static video or a stream Thursday, June 30, 2011 47
  • 48. Video Demo Thursday, June 30, 2011 48
  • 49. Video • Format support varies across browsers • Choose at least two of the three main formats o Safari only supports mp4 Ogg Vorbis MP4 WebM Chrome ✓ ✓ Firefox ✓ ✓ Internet Explorer ✓ Opera ✓ ✓ Safari ✓ Source: http://en.wikipedia.org/wiki/HTML5_video Thursday, June 30, 2011 49
  • 50. Video public Video createVideo() {   Video video = Video.createIfSupported();   if (video == null) {     return null;  }   video.addSource("path/file.ogg", VideoElement.TYPE_OGG);   video.addSource("path/file.mp4", VideoElement.TYPE_MP4);   video.addSource("path/file.webm", VideoElement.TYPE_WEBM);   // Show audio controls.   video.setControls(true);   return video; } Thursday, June 30, 2011 50
  • 51. Video public Video createVideo() {   Video video = Video.createIfSupported();   if (video == null) {     return null;  }   video.addSource("path/file.ogg", VideoElement.TYPE_OGG);   video.addSource("path/file.mp4", VideoElement.TYPE_MP4);   video.addSource("path/file.webm", VideoElement.TYPE_WEBM);   // Show audio controls.   video.setControls(true);   return video; } Thursday, June 30, 2011 51
  • 52. Video public Video createVideo() {   Video video = Video.createIfSupported();   if (video == null) {     return null;  }   video.addSource("path/file.ogg", VideoElement.TYPE_OGG);   video.addSource("path/file.mp4", VideoElement.TYPE_MP4);   video.addSource("path/file.webm", VideoElement.TYPE_WEBM);   // Show audio controls.   video.setControls(true);   return video; } Thursday, June 30, 2011 52
  • 53. Video public Video createVideo() {   Video video = Video.createIfSupported();   if (video == null) {     return null;  }   video.addSource("path/file.ogg", VideoElement.TYPE_OGG);   video.addSource("path/file.mp4", VideoElement.TYPE_MP4);   video.addSource("path/file.webm", VideoElement.TYPE_WEBM);   // Show audio controls.   video.setControls(true);   return video; } Thursday, June 30, 2011 53
  • 54. Agenda • Overview • Local Storage for performance • Visualizations via Canvas • Enrich your app with Audio • Embedding Video in your app • Drag and Drop support • Handling unsupported browser versions • CSS3 makes its way into GWT • Angry Birds / ForPlay Thursday, June 30, 2011 54
  • 55. Drag and Drop • Move stuff around... with style • Associate text or ID with the event • Many types of drag events Thursday, June 30, 2011 55
  • 56. Drag and Drop Demo Thursday, June 30, 2011 56
  • 57. Drag and Drop Make a widget draggable • Set the "draggable" attribute to "true" • Add a DragStart handler • Set data in the DragStart handler Thursday, June 30, 2011 57
  • 58. Drag and Drop Make a widget draggable // Make the widget draggable. Label w = new Label("Drag Me"); w.getElement().setDraggable(Element.DRAGGABLE_TRUE); // Add a DragStartHandler. w.addDragStartHandler(new DragStartHandler() {   public void onDragStart(DragStartEvent event) {     // Required: set data for the event.     event.setData("text", "Hello World");     // Optional: show a copy of the widget under cursor.     event.getDataTransfer().setDragImage(w.getElement(),         10, 10);  } }); Thursday, June 30, 2011 58
  • 59. Drag and Drop Make a widget draggable // Make the widget draggable. Label w = new Label("Drag Me"); w.getElement().setDraggable(Element.DRAGGABLE_TRUE); // Add a DragStartHandler. w.addDragStartHandler(new DragStartHandler() {   public void onDragStart(DragStartEvent event) {     // Required: set data for the event.     event.setData("text", "Hello World");     // Optional: show a copy of the widget under cursor.     event.getDataTransfer().setDragImage(w.getElement(),         10, 10);  } }); Thursday, June 30, 2011 59
  • 60. Drag and Drop Make a widget draggable // Make the widget draggable. Label w = new Label("Drag Me"); w.getElement().setDraggable(Element.DRAGGABLE_TRUE); // Add a DragStartHandler. w.addDragStartHandler(new DragStartHandler() {   public void onDragStart(DragStartEvent event) {     // Required: set data for the event.     event.setData("text", "Hello World");     // Optional: show a copy of the widget under cursor.     event.getDataTransfer().setDragImage(w.getElement(),         10, 10);  } }); Thursday, June 30, 2011 60
  • 61. Drag and Drop Make a widget draggable // Make the widget draggable. Label w = new Label("Drag Me"); w.getElement().setDraggable(Element.DRAGGABLE_TRUE); // Add a DragStartHandler. w.addDragStartHandler(new DragStartHandler() {   public void onDragStart(DragStartEvent event) {     // Required: set data for the event.     event.setData("text", "Hello World");     // Optional: show a copy of the widget under cursor.     event.getDataTransfer().setDragImage(w.getElement(),         10, 10);  } }); Thursday, June 30, 2011 61
  • 62. Drag and Drop Make a widget draggable // Make the widget draggable. Label w = new Label("Drag Me"); w.getElement().setDraggable(Element.DRAGGABLE_TRUE); // Add a DragStartHandler. w.addDragStartHandler(new DragStartHandler() {   public void onDragStart(DragStartEvent event) {     // Required: set data for the event.     event.setData("text", "Hello World");     // Optional: show a copy of the widget under cursor.     event.getDataTransfer().setDragImage(w.getElement(),         10, 10);  } }); Thursday, June 30, 2011 62
  • 63. Drag and Drop Create a target • Add a DragOver handler • Add a Drop handler o Prevent default action o Get the data from the transfer object Thursday, June 30, 2011 63
  • 64. Label target = new Label("Drag onto me"); // Required: You must add a DragOverHandler to // create a target. target.addDragOverHandler(new DragOverHandler() { public void onDragOver(DragOverEvent event) { target.getElement().setBackgroundColor("#ffa"); } }); // Add a DropHandler. target.addDropHandler(new DropHandler() { public void onDrop(DropEvent event) { // Prevent the native text drop. event.preventDefault(); // Get the data out of the event. String data = event.getData("text"); target.setText(data); } }); Thursday, June 30, 2011 64
  • 65. Label target = new Label("Drag onto me"); // Required: You must add a DragOverHandler to // create a target. target.addDragOverHandler(new DragOverHandler() { public void onDragOver(DragOverEvent event) { target.getElement().setBackgroundColor("#ffa"); } }); // Add a DropHandler. target.addDropHandler(new DropHandler() { public void onDrop(DropEvent event) { // Prevent the native text drop. event.preventDefault(); // Get the data out of the event. String data = event.getData("text"); target.setText(data); } }); Thursday, June 30, 2011 65
  • 66. Label target = new Label("Drag onto me"); // Required: You must add a DragOverHandler to // create a target. target.addDragOverHandler(new DragOverHandler() { public void onDragOver(DragOverEvent event) { target.getElement().setBackgroundColor("#ffa"); } }); // Add a DropHandler. target.addDropHandler(new DropHandler() { public void onDrop(DropEvent event) { // Prevent the native text drop. event.preventDefault(); // Get the data out of the event. String data = event.getData("text"); target.setText(data); } }); Thursday, June 30, 2011 66
  • 67. Label target = new Label("Drag onto me"); // Required: You must add a DragOverHandler to // create a target. target.addDragOverHandler(new DragOverHandler() { public void onDragOver(DragOverEvent event) { target.getElement().setBackgroundColor("#ffa"); } }); // Add a DropHandler. target.addDropHandler(new DropHandler() { public void onDrop(DropEvent event) { // Prevent the native text drop. event.preventDefault(); // Get the data out of the event. String data = event.getData("text"); target.setText(data); } }); Thursday, June 30, 2011 67
  • 68. Label target = new Label("Drag onto me"); // Required: You must add a DragOverHandler to // create a target. target.addDragOverHandler(new DragOverHandler() { public void onDragOver(DragOverEvent event) { target.getElement().setBackgroundColor("#ffa"); } }); // Add a DropHandler. target.addDropHandler(new DropHandler() { public void onDrop(DropEvent event) { // Prevent the native text drop. event.preventDefault(); // Get the data out of the event. String data = event.getData("text"); target.setText(data); } }); Thursday, June 30, 2011 68
  • 69. Drag and Drop On any widget • Some widgets do not implement drag handlers • You can always use addDomHandler() to add a handler // Add a DragStartHandler. w.addDomHandler(new DragStartHandler() {   public void onDragStart(DragStartEvent event) {     // Required: set data for the event.     event.setData("text", "Hello World");     // Optional: show a copy of the widget under cursor.     event.getDataTransfer().setDragImage(w.getElement,          10, 10);  } }, DragStartEvent.getType()); Thursday, June 30, 2011 69
  • 70. Drag and Drop + File API? • Spec is still changing rapidly. • Not in GWT (yet!)   File[] files = event.getDataTransfer().getFiles();   // read an entire file   String txt = FileReader.readAsBinaryString(files[0]);   // read a chunk of a file   Reader reader = new Reader();   Blob blob = files[0].slice(startingByte, length);   String txt = reader.readAsBinaryString(blob); Thursday, June 30, 2011 70
  • 71. Drag and Drop Uploader Demo Thursday, June 30, 2011 71
  • 72. Agenda • Overview • Local Storage for performance • Visualizations via Canvas • Enrich your app with Audio • Embedding Video in your app • Drag and Drop support • Handling unsupported browser versions • CSS3 makes its way into GWT • Angry Birds / ForPlay Thursday, June 30, 2011 72
  • 73. Partial Support Because if all browsers supported it, it would be too easy • GWT provides APIs that are not supported in all browsers o Modern browsers gaining market share rapidly • Implementors of PartialSupport provide two static methods: o isSupported() o createIfSupported()  "Compiles out" if on a non-supported permutation! Thursday, June 30, 2011 73
  • 74. Partial Support Fallback to another implementation public void showChart(AcceptsOneWidget panel,     ChartData data) {   Canvas canvas = Canvas.createIfSupported();   if (canvas == null) {     // Fallback to an image if Canvas isn't supported.     String imageUrl = encodeChartData(data);     panel.setWidget(new Image(imageUrl);     return;  }   // Create a canvas chart.   ...   // Display the canvas.   panel.setWidget(canvas); } Thursday, June 30, 2011 74
  • 75. Agenda • Overview • Local Storage for performance • Visualizations via Canvas • Enrich your app with Audio • Embedding Video in your app • Drag and Drop support • Handling unsupported browser versions • CSS3 makes its way into GWT • Angry Birds / ForPlay Thursday, June 30, 2011 75
  • 76. CSS3 Style your GWT app • Nothing special required for CSS3 o Rounded corners, drop shadows, animations, group opacity, multiple backgrounds, 3D transforms, etc. o No changes required for GWT's UIBinder Thursday, June 30, 2011 76
  • 77. CSS3 in GWT's Widgets • As of GWT 2.3, widgets now use CSS3 • On legacy browsers, widgets will be "usable" Example: Rounded Corners Thursday, June 30, 2011 77
  • 78. Agenda • Overview • Local Storage for performance • Visualizations via Canvas • Enrich your app with Audio • Embedding Video in your app • Drag and Drop support • Handling unsupported browser versions • CSS3 makes its way into GWT • Angry Birds / ForPlay Thursday, June 30, 2011 78
  • 79. Angry Birds / ForPlay Demo Thursday, June 30, 2011 79
  • 80. Angry Birds An HTML5 GWT app • Announced at Google IO 2011 • Built with a library called ForPlay o Uses GWT for Java -> HTML5 step. • Uses most of the technologies talked about here o Canvas, Audio*, Storage, CSS3 o Prove it Thursday, June 30, 2011 80
  • 81. Angry Birds An HTML5 GWT app • Announced at Google IO 2011 • Built with a library called ForPlay o Uses GWT for Java -> HTML5 step. • Uses most of the technologies talked about here o Canvas, Audio*, Storage, CSS3 o Prove it • Check out the I/O talk: Kick-Ass Game Programming with Google Web Toolkit • http://goo.gl/UZ4X4 Thursday, June 30, 2011 81
  • 82. ForPlay In 30 seconds • Cross-platform library for games o Cross-browser (HTML5): WebGL, Canvas, 3D CSS o Android, Flash, and Java apps too • Write and debug games using the ForPlay API, compile onto many platforms. • API includes cross-platform abstractions for startup, asset management, input (keyboard, touch, mouse), audio, graphics, physics engine (box2d), json parsing, etc. Thursday, June 30, 2011 82
  • 83. ForPlay An GWT library for games • Some demos o Joel Webber's XNA Platormer port o Aquarium by Mohamed Ousgougou / SFEIR o http://p4cdroid.appspot.com/ o more examples, including source at gwtforplay.com • For more info or if you'd like to join in: http://gwtforplay.com Thursday, June 30, 2011 83
  • 84. GWT + HTML5 GTUG Atlanta David Chandler [email protected] Philip Rogers [email protected] Thursday, June 30, 2011 84