SlideShare une entreprise Scribd logo
1  sur  84
Télécharger pour lire hors ligne
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

Contenu connexe

Similaire à GWT + HTML5: Add Visualizations via Canvas

Sneak Peek of Nuxeo 5.4
Sneak Peek of Nuxeo 5.4Sneak Peek of Nuxeo 5.4
Sneak Peek of Nuxeo 5.4Nuxeo
 
GeoNetwork workshop introduction mapwindow conference 2012 Velp
GeoNetwork workshop introduction mapwindow conference 2012 VelpGeoNetwork workshop introduction mapwindow conference 2012 Velp
GeoNetwork workshop introduction mapwindow conference 2012 Velppvangenuchten
 
GeoSDI: una piattaforma social di dati geografici basata sui principi di INSP...
GeoSDI: una piattaforma social di dati geografici basata sui principi di INSP...GeoSDI: una piattaforma social di dati geografici basata sui principi di INSP...
GeoSDI: una piattaforma social di dati geografici basata sui principi di INSP...Beniamino Murgante
 
OSGeo in Production
OSGeo in ProductionOSGeo in Production
OSGeo in ProductionDavid Zwarg
 
Kotlin for android 2019
Kotlin for android 2019Kotlin for android 2019
Kotlin for android 2019Shady Selim
 
NETConfAR v2017 Workshop Hololens
NETConfAR v2017 Workshop HololensNETConfAR v2017 Workshop Hololens
NETConfAR v2017 Workshop HololensSebastian Gambolati
 
soft-shake.ch - Optimizing iOS applications
soft-shake.ch - Optimizing iOS applicationssoft-shake.ch - Optimizing iOS applications
soft-shake.ch - Optimizing iOS applicationssoft-shake.ch
 
GeoDjango in a nutshell
GeoDjango in a nutshellGeoDjango in a nutshell
GeoDjango in a nutshellDjango Stars
 
Web based interactive big data visualization
Web based interactive big data visualizationWeb based interactive big data visualization
Web based interactive big data visualizationWenli Zhang
 
State of GeoServer 2015
State of GeoServer 2015State of GeoServer 2015
State of GeoServer 2015Jody Garnett
 
Similarity-based retrieval of multimedia content
Similarity-based retrieval of multimedia contentSimilarity-based retrieval of multimedia content
Similarity-based retrieval of multimedia contentSymeon Papadopoulos
 
Creating Hybrid mobile apps with YUI
Creating Hybrid mobile apps with YUICreating Hybrid mobile apps with YUI
Creating Hybrid mobile apps with YUIGonzalo Cordero
 
Doug McCune - Using Open Source Flex and ActionScript Projects
Doug McCune - Using Open Source Flex and ActionScript ProjectsDoug McCune - Using Open Source Flex and ActionScript Projects
Doug McCune - Using Open Source Flex and ActionScript ProjectsDoug McCune
 
AFCEA C4I Symposium: The 4th C in C4I Stands for Cloud:Factors Driving Adopti...
AFCEA C4I Symposium: The 4th C in C4I Stands for Cloud:Factors Driving Adopti...AFCEA C4I Symposium: The 4th C in C4I Stands for Cloud:Factors Driving Adopti...
AFCEA C4I Symposium: The 4th C in C4I Stands for Cloud:Factors Driving Adopti...Patrick Chanezon
 
DemoCamp Budapest 2016 - Introdcution
DemoCamp Budapest 2016 - IntrodcutionDemoCamp Budapest 2016 - Introdcution
DemoCamp Budapest 2016 - IntrodcutionÁkos Horváth
 
2010-06 - a smalltalk about salesforce.com with java architects at YaJuG
2010-06 - a smalltalk about salesforce.com with java architects at YaJuG2010-06 - a smalltalk about salesforce.com with java architects at YaJuG
2010-06 - a smalltalk about salesforce.com with java architects at YaJuGYves Leblond
 
Screencasting and Presenting for Engineers
Screencasting and Presenting for EngineersScreencasting and Presenting for Engineers
Screencasting and Presenting for EngineersKunal Johar
 
Advanced Data Widgets and Server Integration
Advanced Data Widgets and Server IntegrationAdvanced Data Widgets and Server Integration
Advanced Data Widgets and Server IntegrationSencha
 
Android casting-wide-net-android-devices
Android casting-wide-net-android-devicesAndroid casting-wide-net-android-devices
Android casting-wide-net-android-devicesMarakana Inc.
 

Similaire à GWT + HTML5: Add Visualizations via Canvas (20)

Sneak Peek of Nuxeo 5.4
Sneak Peek of Nuxeo 5.4Sneak Peek of Nuxeo 5.4
Sneak Peek of Nuxeo 5.4
 
GeoNetwork workshop introduction mapwindow conference 2012 Velp
GeoNetwork workshop introduction mapwindow conference 2012 VelpGeoNetwork workshop introduction mapwindow conference 2012 Velp
GeoNetwork workshop introduction mapwindow conference 2012 Velp
 
GeoSDI: una piattaforma social di dati geografici basata sui principi di INSP...
GeoSDI: una piattaforma social di dati geografici basata sui principi di INSP...GeoSDI: una piattaforma social di dati geografici basata sui principi di INSP...
GeoSDI: una piattaforma social di dati geografici basata sui principi di INSP...
 
OSGeo in Production
OSGeo in ProductionOSGeo in Production
OSGeo in Production
 
Kotlin for android 2019
Kotlin for android 2019Kotlin for android 2019
Kotlin for android 2019
 
NETConfAR v2017 Workshop Hololens
NETConfAR v2017 Workshop HololensNETConfAR v2017 Workshop Hololens
NETConfAR v2017 Workshop Hololens
 
soft-shake.ch - Optimizing iOS applications
soft-shake.ch - Optimizing iOS applicationssoft-shake.ch - Optimizing iOS applications
soft-shake.ch - Optimizing iOS applications
 
GeoDjango in a nutshell
GeoDjango in a nutshellGeoDjango in a nutshell
GeoDjango in a nutshell
 
Web based interactive big data visualization
Web based interactive big data visualizationWeb based interactive big data visualization
Web based interactive big data visualization
 
State of GeoServer 2015
State of GeoServer 2015State of GeoServer 2015
State of GeoServer 2015
 
Similarity-based retrieval of multimedia content
Similarity-based retrieval of multimedia contentSimilarity-based retrieval of multimedia content
Similarity-based retrieval of multimedia content
 
Creating Hybrid mobile apps with YUI
Creating Hybrid mobile apps with YUICreating Hybrid mobile apps with YUI
Creating Hybrid mobile apps with YUI
 
Doug McCune - Using Open Source Flex and ActionScript Projects
Doug McCune - Using Open Source Flex and ActionScript ProjectsDoug McCune - Using Open Source Flex and ActionScript Projects
Doug McCune - Using Open Source Flex and ActionScript Projects
 
AFCEA C4I Symposium: The 4th C in C4I Stands for Cloud:Factors Driving Adopti...
AFCEA C4I Symposium: The 4th C in C4I Stands for Cloud:Factors Driving Adopti...AFCEA C4I Symposium: The 4th C in C4I Stands for Cloud:Factors Driving Adopti...
AFCEA C4I Symposium: The 4th C in C4I Stands for Cloud:Factors Driving Adopti...
 
DemoCamp Budapest 2016 - Introdcution
DemoCamp Budapest 2016 - IntrodcutionDemoCamp Budapest 2016 - Introdcution
DemoCamp Budapest 2016 - Introdcution
 
2010-06 - a smalltalk about salesforce.com with java architects at YaJuG
2010-06 - a smalltalk about salesforce.com with java architects at YaJuG2010-06 - a smalltalk about salesforce.com with java architects at YaJuG
2010-06 - a smalltalk about salesforce.com with java architects at YaJuG
 
Screencasting and Presenting for Engineers
Screencasting and Presenting for EngineersScreencasting and Presenting for Engineers
Screencasting and Presenting for Engineers
 
Html5 Future of WEB
Html5 Future of WEBHtml5 Future of WEB
Html5 Future of WEB
 
Advanced Data Widgets and Server Integration
Advanced Data Widgets and Server IntegrationAdvanced Data Widgets and Server Integration
Advanced Data Widgets and Server Integration
 
Android casting-wide-net-android-devices
Android casting-wide-net-android-devicesAndroid casting-wide-net-android-devices
Android casting-wide-net-android-devices
 

Plus de David Chandler

Taking Your GWT App to Tablets with GXT 4.0
Taking Your GWT App to Tablets with GXT 4.0Taking Your GWT App to Tablets with GXT 4.0
Taking Your GWT App to Tablets with GXT 4.0David Chandler
 
StORM: a lightweight ORM for Android SQLite
StORM: a lightweight ORM for Android SQLiteStORM: a lightweight ORM for Android SQLite
StORM: a lightweight ORM for Android SQLiteDavid Chandler
 
Easy REST APIs with Jersey and RestyGWT
Easy REST APIs with Jersey and RestyGWTEasy REST APIs with Jersey and RestyGWT
Easy REST APIs with Jersey and RestyGWTDavid Chandler
 
Cómo trabajan los Googlers
Cómo trabajan los GooglersCómo trabajan los Googlers
Cómo trabajan los GooglersDavid Chandler
 
Google App Engine Update 2012
Google App Engine Update 2012Google App Engine Update 2012
Google App Engine Update 2012David Chandler
 
Scalable Apps with Google App Engine
Scalable Apps with Google App EngineScalable Apps with Google App Engine
Scalable Apps with Google App EngineDavid Chandler
 
Develop and Deploy Scalable Apps with Google App Engine
Develop and Deploy Scalable Apps with Google App EngineDevelop and Deploy Scalable Apps with Google App Engine
Develop and Deploy Scalable Apps with Google App EngineDavid Chandler
 
The 90-Day Startup with Google AppEngine for Java
The 90-Day Startup with Google AppEngine for JavaThe 90-Day Startup with Google AppEngine for Java
The 90-Day Startup with Google AppEngine for JavaDavid Chandler
 
Securing JSF Applications Against the OWASP Top Ten
Securing JSF Applications Against the OWASP Top TenSecuring JSF Applications Against the OWASP Top Ten
Securing JSF Applications Against the OWASP Top TenDavid Chandler
 

Plus de David Chandler (13)

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

Dernier

Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Scott Andery
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditSkynet Technologies
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 

Dernier (20)

Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance Audit
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 

GWT + HTML5: Add Visualizations via Canvas

  • 1. GWT + HTML5 GTUG Atlanta David Chandler drfibonacci@google.com Philip Rogers pdr@google.com 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 drfibonacci@google.com Philip Rogers pdr@google.com Thursday, June 30, 2011 84