SlideShare uma empresa Scribd logo
1 de 28
Baixar para ler offline
Designing a
JavaFX Mobile
application

Fabrizio Giudici
Tidalwave s.a.s.
214
AGENDA

> Putting JavaFX (Mobile) in context
> My case study
> Main features of JavaFX (Mobile)
> JavaFX Mobile through a few examples
> Current status of JavaFX Mobile
> Conclusion




                                         2
About the speaker

> Fabrizio.Giudici@tidalwave.it
> Senior Architect, Mentor, Technical Writer
> Working with Java (all the editions, plus exotic stuff) since 1996
> Working with Java ME since 1999
   –   First J2ME edition at JavaOne™ (Palm)
   –   Developed a couple of research projects with the University of Genoa
   –   Developed a couple of customer projects with my former company
   –   Consulting for customer projects
   –   Author of mobile FLOSS: windRose and blueBill Mobile
> Co-leader of JUG Milano


                                                                              3
What's wrong with JME

> Everything was so good at the old, Palm times
  – Small devices → no big expectations
   –   One reference platform
   –   One pervasive runtime
> With more devices, JME got fragmented
  – JSR as extension points (e.g. bluetooth, location)
   –   Multiple combinations
   –   Harder and harder to test
   –   windRose pain



                                                         4
Hoping in Java FX Mobile

> JavaFX announced by Sun Microsystems in 2007
  – A specific scripting language + a runtime
   –   Fight the “Ugly Java UI stereotype”
   –   Re-designed UI controls
   –   Integration with graphics designers workflow (e.g. NetBeans + Photoshop)
   –   Profiles for multiple targets (desktop / web, mobile)
> JavaFX Mobile profile
  – Can sit on top of JME (MSA: Mobile Service Architecture, a.k.a. JSR-248)
   –   Maybe no more (or reduced) fragmentation?
> Oracle commitment after the Sun buy
> A fulfilled promise?
   –   Answers at the end :-)                                                     5
My case study: blueBill Mobile

> “The field tool for birdwatchers”
  – Records geotagged observations
   –   Reference guides with multimedia
   –   Social capabilities (à la Google Friends)
> Started in 2009 with JavaFX
> Currently the most advanced version is the Android one
   –   JavaFX version being redesigned (more later)
> Demo




                                                           6
Main features of JavaFX

> The languages is both imperative and declarative
  – Imperative: for normal processing
   –   Declarative: mostly for the UI (no XML, no separate layout descriptor)
              Binding
   –   Has got closures, mixins
> Compiles to the same VM bytecode
  – Can mix with Java code (e.g. reference a Java library)
   –   On the desktop, can be mixed with Swing (in addition to its own UI widgets)
   –   On the mobile, runs its own UI widgets




                                                                                     7
Some code examples

> Example 1: Calling JME code
> Example 2: Posting contents (REST)
> Example 3: Getting resources (REST)
> Example 4: Binding (if time allows)




                                        8
Example: calling JME code

> Not much to say: it just works
package it.tidalwave.bluebillmfx;

import   javax.microedition.location.Criteria;
import   javax.microedition.location.LocationProvider;
import   javafx.animation.Timeline;
import   javafx.animation.KeyFrame;
import   it.tidalwave.geo.mapfx.model.Coordinates;

public class PositionTracker
  {
    public-read var currentPosition : Coordinates;
    def criteria = new Criteria();
    var locationProvider : LocationProvider;

    postinit {
        locationProvider = LocationProvider.getInstance(criteria);
        pollingTimeline.play();
      }


                                                                     9
Example: calling JME code

> Need to copy data in JavaFX classes if you want binding support
     function getPosition(): Void {
         def location = locationProvider.getLocation(5); // JME stuff
         def coordinates = location.getQualifiedCoordinates();

           if (coordinates != null ) {
               def lat = coordinates.getLatitude();
               def lon = coordinates.getLongitude();
               currentPosition = Coordinates { latitude: lat; longitude: lon };
             }
       }

     def pollingTimeline = Timeline {
          repeatCount: Timeline.INDEFINITE
          keyFrames:   KeyFrame { time: 10s; action: periodicTask }
       };

     function periodicTask(): Void {
         getPosition();
         // update the map position, etc...
       }
 }                                                                                10
Example: posting contents

> HttpRequest provides a skeleton
public class ObservationRDFUpload extends HttpRequest
  {
    public-init var serviceURL = "http://myHost:8084/blueBillGeoService";

      override public var method = HttpRequest.POST;

      public var content : String;

      override var output on replace {
          if (output != null) {
              output.write(content.getBytes());
              output.close();
            }
        }

      override function start(): Void {
          location = "{serviceURL}/postObservation"; // REST call
          setHeader("Content-Type", "application/rdf");
          super.start();
        }
  }                                                                         11
Example: posting contents

> HttpRequest provides a skeleton

 def upload = ObservationRDFUpload
   {
      content: // ... assemble the string with the contents
   };

 upload.start();




                                                              12
Example: reading resources

> The relevant model class
public class Taxon
  {
    public-read protected var id : String;
    public-read var urlsLoaded = false;
    var urlsLoading = false;
    var imageURLs : String[]; // [] is a list (“sequence”), not an array
    var images : DeferredImage[];

    public bound function getImage (index : Integer): DeferredImage {
        def dummy = loadImageURLs(); // assignment is a requirement for the bound function
        return images[index];
      }

    public bound function imageCount(): Integer {
        return sizeof images;
      }




                                                                                             13
Example: reading resources

> Getting a JSON resource catalog
  function loadImageURLs(): Boolean {
      if (not urlsLoading and not urlsLoaded) {
          urlsLoading = true;
          def fixedId = clean(id); // get rid of/escape “bad” chars such as :, #, etc...
          def url = "http://kenai.com/svn/bluebill-mobile~media/catalog/{fixedId}.json";

         def request : HttpRequest = HttpRequest { // mere instantiation, not subclassing!
             location: url;
             method:   HttpRequest.GET;

              onInput: function (is: InputStream) { // hey, this is not a switch() label!
                  if (request.responseCode != 200) {
                      imageURLs = "media/black_glossy_web20_icon_012.png";
                    }
                  else {
                      try {
                          def parser = PullParser { documentType: PullParser.JSON;
                                                    input: is; onEvent: parseEventCallback };
                          parser.parse();
                        }
                      catch (e: Exception) {
                          println("Exception {e} while parsing {url}");
                        }
                      finally {
                          is.close();                                                           14
                        }
                    }
                }
Example: reading resources

> Getting a JSON resource catalog
                     onException: function (e: Exception) {
                         imageURLs = "media/black_glossy_web20_icon_012.png";
                         urlsLoaded = true;
                       }

                     onDone: function() {
                         images = for (url in imageURLs) {
                             DeferredImage { url: url };
                           }

                          imageURLs = null;
                          urlsLoaded = true;
                      }
                 }

               request.start();
           }

         return urlsLoaded;
     }

  def parseEventCallback = function (event: Event): Void {
       if ((event.type == PullParser.TEXT) and (event.name == "url")) {
           insert event.text into imageURLs;
         }                                                                      15
     }
 }
Example: reading resources

> Loading an image
> JavaFX Image loads automatically when initialized
var imageCounter = 0;
public class DeferredImage
  {
    public-init var url : String;
    public-read var progress = bind image.progress;
    public-read var error = bind image.error;
    def id = imageCounter++;
    public-read var image : Image;

      public function load() { // start loading only when load() is called
          if (image == null)
            {
              image = Image {
                  url: url
                  backgroundLoading: true
                }
            }
        }                                                                    16
  }
Example: binding

> Introducing TaxonSearchController
  – Manages a list of Taxons
   –   Produces a filtered list of Taxons whose names match a substring
   –   Provides a hint for autocompletion
               Eg. you type “He”
               That matches only “Heron ***”
               Hints is “Heron “




                                                                          17
Example: binding

> Some relevant parts of Taxon
public class Taxon
  {
    public-read protected var displayName : String;
    public-read protected var scientificName : String;
    public-read protected var id : String;

      override function toString() {
          return "{displayName} ({scientificName}) ({id})"
        }
  }




                                                             18
Example: binding

> TaxonSearchController (1/3)
public class TaxonSearchController
  {
    public var taxons: Taxon[];
    public var filteredTaxons: Taxon[];
    public var selectedTaxonIndex : Integer = -1; // set from the UI

    public var selectedTaxon = bind
      if (selectedTaxonIndex < 0) then null
                                  else filteredTaxons[selectedTaxonIndex];

    // setting this property will trigger filtering
    public var filter = "" on replace {
        filteredTaxons = taxons[taxon | matches(taxon, filter)];
        updateHint();
      }

    public-read var hint = ""; // the auto-completed hint



                                                                             19
Example: binding

> TaxonSearchController (2/3)
   protected function matches (taxon : Taxon, string: String) : Boolean {
       if (string == "") {
            return true;
         }
       if (taxon.displayName.toLowerCase().startsWith(string.toLowerCase())) {
            return true;
           // more complex in the real case, as it also deals with scientific name
           // but not relevant now
         }
       return false;
     }




                                                                                     20
Example: binding

> TaxonSearchController (3/3)
     protected function updateHint(): Void {
         def hintTry = commonLeadingSubstring(filteredTaxons);
         //
         // Sometimes it can't find a better auto-completion than the current filter,
         //
         hint = if (hintTry.length() > filter.length())
                         then hintTry
                         else filter;
       }

 }




                                                                                        21
Example: binding

> TaxonSearchScreen
public class TaxonSearchScreen extends Container // e.g. a UI panel
  {
    // warning: there are some simplifications, but the concepts are here
    public-read def controller = TaxonSearchController {
         selectedTaxonIndex: bind list.selectedIndex;
      }
    def list = ListBox { // the list widget in the UI
         items: bind controller.filteredTaxons
      };

   def hint = bind controller.hint on replace {
       if (hint != "") {
           filter = hint;
         }
     }
   var resetSelectionWhenFilterChanges = bind controller.selectedTaxon on replace {
       if (controller.selectedTaxon != null) {
           list.selectedIndex = 0;
         }
     }
   TextBox { // a text input box in the UI
       text: bind controller.filter with inverse
     }
   Text { // a label rendering a text in the UI
       content: bind "{sizeof controller.filteredTaxons} specie(s)"                   22
     }
JavaFX mobile in 2009

> Development tools available (emulator, etc...)
> First capable phones at J1: LG Incite, HTC Touch Diamond
> Announced a “JavaFX Mobile player”
  – Would run JavaFX on MSA (JSR 248) JME phones
> Looked very promising
  – That's why blueBill Mobile started with it




                                                             23
Status updates in 2010

> Barcelona Mobile World Congress 2010
  – “Feature phones” (Qualcomm and the Brew Mobile Platform OS)
   –   Sony-Ericsson in “upcoming phones”
> Recent phone status update (JavaFX forums, March 16, 2010)
  – LG Incite, HTC Touch Diamond... still!
   –   “Unofficially” runs on any Windows Mobile 6.x device (e.g. HTC HD2)
> JavaFX 1.3 released on May 14, 2010
  – Shares many improvements with the desktop/web profile
   –   Mobile emulator runs on Mac OS X
> JavaFX Mobile Player MIA (I mean, it's Windows Mobile only)
> No further manufacturer endorsements?
                                                                             24
My view of Java-related mobile solutions

> We're in the climax of the “next generation mobile” war
  – iPhone/iPad, Android leading on the growth rates
   –   Adobe Flash at stake, but if it survives will be relevant
> Is there still room for JavaFX Mobile? JME?
> JavaFX Mobile
   –   Still excites me, technically
   –   The Oracle-Sun deal might have slowed down deals – but...
   –   … timing out this Summer
   –Hoping in a specific Android port/adaptation (using the Android UI/runtime)
               Hearing a few people talking about that
               Would bring-in e.g. the integration with graphic designer workflow
> JME still relevant for the “glorious old guard” (Nokia, etc..., BlackBerry)
  – “Oldies but goodies”                                                         25
My research for the Summer

> Two/threefold strategy
  – Android (it delivers, short time-to-market)
   –   JME (catch the “old glorious guard”)
   –   JavaFX (if industry endorsements / Android support will show up)
> Study whether it is possible to reuse code
  – Not thinking of “catch-all” frameworks
   –   Reusing only the models, writing ad-hoc UIs (no “GCD syndrome”)
   –   Maven for re-using artifacts
   –   Byte-code manipulation (e.g. RetroWeaver) for fitting JME Java 1.3?
   –   Follow my blog and my space at Dzone.com
> The “new” blueBill Mobile for JavaFX code is not yet available
  – Under heavy refactoring, catching up with the Android version            26
Questions?

> Thanks for your attention
  – http://javafx.com
   –   http://bluebill.tidalwave.it/mobile
   –   http://windrose.tidalwave.it




                                             27
Fabrizio Giudici   www.tidalwave.it
Tidalwave s.a.s.   fabrizio.giudici@
                   tidalwave.it

Mais conteúdo relacionado

Mais procurados

Web2py tutorial to create db driven application.
Web2py tutorial to create db driven application.Web2py tutorial to create db driven application.
Web2py tutorial to create db driven application.
fRui Apps
 
A Gentle Introduction To Object Oriented Php
A Gentle Introduction To Object Oriented PhpA Gentle Introduction To Object Oriented Php
A Gentle Introduction To Object Oriented Php
Michael Girouard
 
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby DeveloperVenturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Jon Kruger
 
ZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODMZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODM
Jonathan Wage
 

Mais procurados (18)

J query1
J query1J query1
J query1
 
CSharp Advanced L05-Attributes+Reflection
CSharp Advanced L05-Attributes+ReflectionCSharp Advanced L05-Attributes+Reflection
CSharp Advanced L05-Attributes+Reflection
 
Web2py tutorial to create db driven application.
Web2py tutorial to create db driven application.Web2py tutorial to create db driven application.
Web2py tutorial to create db driven application.
 
Class-based views with Django
Class-based views with DjangoClass-based views with Django
Class-based views with Django
 
A Gentle Introduction To Object Oriented Php
A Gentle Introduction To Object Oriented PhpA Gentle Introduction To Object Oriented Php
A Gentle Introduction To Object Oriented Php
 
Dartprogramming
DartprogrammingDartprogramming
Dartprogramming
 
Synapseindia object oriented programming in php
Synapseindia object oriented programming in phpSynapseindia object oriented programming in php
Synapseindia object oriented programming in php
 
java script
java scriptjava script
java script
 
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby DeveloperVenturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
 
Java for beginners
Java for beginnersJava for beginners
Java for beginners
 
jQuery-1-Ajax
jQuery-1-AjaxjQuery-1-Ajax
jQuery-1-Ajax
 
ZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODMZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODM
 
Java script
Java scriptJava script
Java script
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the Trenches
 
Doctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document MapperDoctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document Mapper
 
Xtext Eclipse Con
Xtext Eclipse ConXtext Eclipse Con
Xtext Eclipse Con
 
Jackson beyond JSON: XML, CSV
Jackson beyond JSON: XML, CSVJackson beyond JSON: XML, CSV
Jackson beyond JSON: XML, CSV
 
KAAccessControl
KAAccessControlKAAccessControl
KAAccessControl
 

Destaque

Destaque (7)

JavaFX and HTML5 - Like Curds and Rice
JavaFX and HTML5 - Like Curds and RiceJavaFX and HTML5 - Like Curds and Rice
JavaFX and HTML5 - Like Curds and Rice
 
Moving to the Client - JavaFX and HTML5
Moving to the Client - JavaFX and HTML5Moving to the Client - JavaFX and HTML5
Moving to the Client - JavaFX and HTML5
 
Building RIA Applications with JavaFX
Building RIA Applications with JavaFXBuilding RIA Applications with JavaFX
Building RIA Applications with JavaFX
 
JavaFX Advanced
JavaFX AdvancedJavaFX Advanced
JavaFX Advanced
 
JavaFX Versus HTML5 - JavaOne 2014
JavaFX Versus HTML5 - JavaOne 2014JavaFX Versus HTML5 - JavaOne 2014
JavaFX Versus HTML5 - JavaOne 2014
 
JavaFX on Mobile (by Johan Vos)
JavaFX on Mobile (by Johan Vos)JavaFX on Mobile (by Johan Vos)
JavaFX on Mobile (by Johan Vos)
 
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
 

Semelhante a Designing a JavaFX Mobile application

How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js framework
Ben Lin
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
David Padbury
 
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
Nick Sieger
 
Overview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web FrameworkOverview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web Framework
IndicThreads
 
Scala based Lift Framework
Scala based Lift FrameworkScala based Lift Framework
Scala based Lift Framework
vhazrati
 
BlackBerry DevCon 2011 - PhoneGap and WebWorks
BlackBerry DevCon 2011 - PhoneGap and WebWorksBlackBerry DevCon 2011 - PhoneGap and WebWorks
BlackBerry DevCon 2011 - PhoneGap and WebWorks
mwbrooks
 
The Beauty Of Java Script V5a
The Beauty Of Java Script V5aThe Beauty Of Java Script V5a
The Beauty Of Java Script V5a
rajivmordani
 

Semelhante a Designing a JavaFX Mobile application (20)

How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js framework
 
ES6 metaprogramming unleashed
ES6 metaprogramming unleashedES6 metaprogramming unleashed
ES6 metaprogramming unleashed
 
Google Cloud Endpoints: Building Third-Party APIs on Google AppEngine
Google Cloud Endpoints: Building Third-Party APIs on Google AppEngineGoogle Cloud Endpoints: Building Third-Party APIs on Google AppEngine
Google Cloud Endpoints: Building Third-Party APIs on Google AppEngine
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 
Lazy Loading Because I'm Lazy
Lazy Loading Because I'm LazyLazy Loading Because I'm Lazy
Lazy Loading Because I'm Lazy
 
GradleFX
GradleFXGradleFX
GradleFX
 
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
 
Overview Of Lift Framework
Overview Of Lift FrameworkOverview Of Lift Framework
Overview Of Lift Framework
 
Overview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web FrameworkOverview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web Framework
 
Scala based Lift Framework
Scala based Lift FrameworkScala based Lift Framework
Scala based Lift Framework
 
async/await in Swift
async/await in Swiftasync/await in Swift
async/await in Swift
 
Plugin-based software design with Ruby and RubyGems
Plugin-based software design with Ruby and RubyGemsPlugin-based software design with Ruby and RubyGems
Plugin-based software design with Ruby and RubyGems
 
Asynchronous Interfaces
Asynchronous InterfacesAsynchronous Interfaces
Asynchronous Interfaces
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScript
 
BlackBerry DevCon 2011 - PhoneGap and WebWorks
BlackBerry DevCon 2011 - PhoneGap and WebWorksBlackBerry DevCon 2011 - PhoneGap and WebWorks
BlackBerry DevCon 2011 - PhoneGap and WebWorks
 
The Beauty Of Java Script V5a
The Beauty Of Java Script V5aThe Beauty Of Java Script V5a
The Beauty Of Java Script V5a
 
Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications  Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications
 
OSGi ecosystems compared on Apache Karaf - Christian Schneider
OSGi ecosystems compared on Apache Karaf - Christian SchneiderOSGi ecosystems compared on Apache Karaf - Christian Schneider
OSGi ecosystems compared on Apache Karaf - Christian Schneider
 
Multilingualism makes better programmers
Multilingualism makes better programmersMultilingualism makes better programmers
Multilingualism makes better programmers
 
The Beauty of Java Script
The Beauty of Java ScriptThe Beauty of Java Script
The Beauty of Java Script
 

Mais de Fabrizio Giudici

NOSQL also means RDF stores: an Android case study
NOSQL also means RDF stores: an Android case studyNOSQL also means RDF stores: an Android case study
NOSQL also means RDF stores: an Android case study
Fabrizio Giudici
 
Tools for an effective software factory
Tools for an effective software factoryTools for an effective software factory
Tools for an effective software factory
Fabrizio Giudici
 
Parallel Computing Scenarios and the new challenges for the Software Architect
Parallel Computing Scenarios  and the new challenges for the Software ArchitectParallel Computing Scenarios  and the new challenges for the Software Architect
Parallel Computing Scenarios and the new challenges for the Software Architect
Fabrizio Giudici
 
blueMarine a desktop app for the open source photographic workflow
blueMarine  a desktop app for the open source photographic workflowblueMarine  a desktop app for the open source photographic workflow
blueMarine a desktop app for the open source photographic workflow
Fabrizio Giudici
 
blueMarine photographic workflow with Java
blueMarine photographic workflow with JavablueMarine photographic workflow with Java
blueMarine photographic workflow with Java
Fabrizio Giudici
 
blueMarine Sailing with NetBeans Platform
blueMarine Sailing with NetBeans PlatformblueMarine Sailing with NetBeans Platform
blueMarine Sailing with NetBeans Platform
Fabrizio Giudici
 
NASA World Wind for Java API Overview
NASA World Wind for Java  API OverviewNASA World Wind for Java  API Overview
NASA World Wind for Java API Overview
Fabrizio Giudici
 
Web Development with Apache Struts 2
Web Development with  Apache Struts 2Web Development with  Apache Struts 2
Web Development with Apache Struts 2
Fabrizio Giudici
 
blueMarine Or Why You Should Really Ship Swing Applications
blueMarine  Or Why You Should Really Ship Swing  Applications blueMarine  Or Why You Should Really Ship Swing  Applications
blueMarine Or Why You Should Really Ship Swing Applications
Fabrizio Giudici
 

Mais de Fabrizio Giudici (16)

Building Android apps with Maven
Building Android apps with MavenBuilding Android apps with Maven
Building Android apps with Maven
 
DCI - Data, Context and Interaction @ Jug Lugano May 2011
DCI - Data, Context and Interaction @ Jug Lugano May 2011 DCI - Data, Context and Interaction @ Jug Lugano May 2011
DCI - Data, Context and Interaction @ Jug Lugano May 2011
 
DCI - Data, Context and Interaction @ Jug Genova April 2011
DCI - Data, Context and Interaction @ Jug Genova April 2011DCI - Data, Context and Interaction @ Jug Genova April 2011
DCI - Data, Context and Interaction @ Jug Genova April 2011
 
NOSQL also means RDF stores: an Android case study
NOSQL also means RDF stores: an Android case studyNOSQL also means RDF stores: an Android case study
NOSQL also means RDF stores: an Android case study
 
Netbeans+platform+maven
Netbeans+platform+mavenNetbeans+platform+maven
Netbeans+platform+maven
 
Tools for an effective software factory
Tools for an effective software factoryTools for an effective software factory
Tools for an effective software factory
 
Parallel Computing Scenarios and the new challenges for the Software Architect
Parallel Computing Scenarios  and the new challenges for the Software ArchitectParallel Computing Scenarios  and the new challenges for the Software Architect
Parallel Computing Scenarios and the new challenges for the Software Architect
 
blueMarine a desktop app for the open source photographic workflow
blueMarine  a desktop app for the open source photographic workflowblueMarine  a desktop app for the open source photographic workflow
blueMarine a desktop app for the open source photographic workflow
 
blueMarine photographic workflow with Java
blueMarine photographic workflow with JavablueMarine photographic workflow with Java
blueMarine photographic workflow with Java
 
blueMarine Sailing with NetBeans Platform
blueMarine Sailing with NetBeans PlatformblueMarine Sailing with NetBeans Platform
blueMarine Sailing with NetBeans Platform
 
NASA World Wind for Java API Overview
NASA World Wind for Java  API OverviewNASA World Wind for Java  API Overview
NASA World Wind for Java API Overview
 
The VRC Project
The VRC ProjectThe VRC Project
The VRC Project
 
Web Development with Apache Struts 2
Web Development with  Apache Struts 2Web Development with  Apache Struts 2
Web Development with Apache Struts 2
 
blueMarine Or Why You Should Really Ship Swing Applications
blueMarine  Or Why You Should Really Ship Swing  Applications blueMarine  Or Why You Should Really Ship Swing  Applications
blueMarine Or Why You Should Really Ship Swing Applications
 
Android java fx-jme@jug-lugano
Android java fx-jme@jug-luganoAndroid java fx-jme@jug-lugano
Android java fx-jme@jug-lugano
 
Mercurial
MercurialMercurial
Mercurial
 

Último

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Último (20)

A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 

Designing a JavaFX Mobile application

  • 1. Designing a JavaFX Mobile application Fabrizio Giudici Tidalwave s.a.s. 214
  • 2. AGENDA > Putting JavaFX (Mobile) in context > My case study > Main features of JavaFX (Mobile) > JavaFX Mobile through a few examples > Current status of JavaFX Mobile > Conclusion 2
  • 3. About the speaker > Fabrizio.Giudici@tidalwave.it > Senior Architect, Mentor, Technical Writer > Working with Java (all the editions, plus exotic stuff) since 1996 > Working with Java ME since 1999 – First J2ME edition at JavaOne™ (Palm) – Developed a couple of research projects with the University of Genoa – Developed a couple of customer projects with my former company – Consulting for customer projects – Author of mobile FLOSS: windRose and blueBill Mobile > Co-leader of JUG Milano 3
  • 4. What's wrong with JME > Everything was so good at the old, Palm times – Small devices → no big expectations – One reference platform – One pervasive runtime > With more devices, JME got fragmented – JSR as extension points (e.g. bluetooth, location) – Multiple combinations – Harder and harder to test – windRose pain 4
  • 5. Hoping in Java FX Mobile > JavaFX announced by Sun Microsystems in 2007 – A specific scripting language + a runtime – Fight the “Ugly Java UI stereotype” – Re-designed UI controls – Integration with graphics designers workflow (e.g. NetBeans + Photoshop) – Profiles for multiple targets (desktop / web, mobile) > JavaFX Mobile profile – Can sit on top of JME (MSA: Mobile Service Architecture, a.k.a. JSR-248) – Maybe no more (or reduced) fragmentation? > Oracle commitment after the Sun buy > A fulfilled promise? – Answers at the end :-) 5
  • 6. My case study: blueBill Mobile > “The field tool for birdwatchers” – Records geotagged observations – Reference guides with multimedia – Social capabilities (à la Google Friends) > Started in 2009 with JavaFX > Currently the most advanced version is the Android one – JavaFX version being redesigned (more later) > Demo 6
  • 7. Main features of JavaFX > The languages is both imperative and declarative – Imperative: for normal processing – Declarative: mostly for the UI (no XML, no separate layout descriptor)  Binding – Has got closures, mixins > Compiles to the same VM bytecode – Can mix with Java code (e.g. reference a Java library) – On the desktop, can be mixed with Swing (in addition to its own UI widgets) – On the mobile, runs its own UI widgets 7
  • 8. Some code examples > Example 1: Calling JME code > Example 2: Posting contents (REST) > Example 3: Getting resources (REST) > Example 4: Binding (if time allows) 8
  • 9. Example: calling JME code > Not much to say: it just works package it.tidalwave.bluebillmfx; import javax.microedition.location.Criteria; import javax.microedition.location.LocationProvider; import javafx.animation.Timeline; import javafx.animation.KeyFrame; import it.tidalwave.geo.mapfx.model.Coordinates; public class PositionTracker { public-read var currentPosition : Coordinates; def criteria = new Criteria(); var locationProvider : LocationProvider; postinit { locationProvider = LocationProvider.getInstance(criteria); pollingTimeline.play(); } 9
  • 10. Example: calling JME code > Need to copy data in JavaFX classes if you want binding support function getPosition(): Void { def location = locationProvider.getLocation(5); // JME stuff def coordinates = location.getQualifiedCoordinates(); if (coordinates != null ) { def lat = coordinates.getLatitude(); def lon = coordinates.getLongitude(); currentPosition = Coordinates { latitude: lat; longitude: lon }; } } def pollingTimeline = Timeline { repeatCount: Timeline.INDEFINITE keyFrames: KeyFrame { time: 10s; action: periodicTask } }; function periodicTask(): Void { getPosition(); // update the map position, etc... } } 10
  • 11. Example: posting contents > HttpRequest provides a skeleton public class ObservationRDFUpload extends HttpRequest { public-init var serviceURL = "http://myHost:8084/blueBillGeoService"; override public var method = HttpRequest.POST; public var content : String; override var output on replace { if (output != null) { output.write(content.getBytes()); output.close(); } } override function start(): Void { location = "{serviceURL}/postObservation"; // REST call setHeader("Content-Type", "application/rdf"); super.start(); } } 11
  • 12. Example: posting contents > HttpRequest provides a skeleton def upload = ObservationRDFUpload { content: // ... assemble the string with the contents }; upload.start(); 12
  • 13. Example: reading resources > The relevant model class public class Taxon { public-read protected var id : String; public-read var urlsLoaded = false; var urlsLoading = false; var imageURLs : String[]; // [] is a list (“sequence”), not an array var images : DeferredImage[]; public bound function getImage (index : Integer): DeferredImage { def dummy = loadImageURLs(); // assignment is a requirement for the bound function return images[index]; } public bound function imageCount(): Integer { return sizeof images; } 13
  • 14. Example: reading resources > Getting a JSON resource catalog function loadImageURLs(): Boolean { if (not urlsLoading and not urlsLoaded) { urlsLoading = true; def fixedId = clean(id); // get rid of/escape “bad” chars such as :, #, etc... def url = "http://kenai.com/svn/bluebill-mobile~media/catalog/{fixedId}.json"; def request : HttpRequest = HttpRequest { // mere instantiation, not subclassing! location: url; method: HttpRequest.GET; onInput: function (is: InputStream) { // hey, this is not a switch() label! if (request.responseCode != 200) { imageURLs = "media/black_glossy_web20_icon_012.png"; } else { try { def parser = PullParser { documentType: PullParser.JSON; input: is; onEvent: parseEventCallback }; parser.parse(); } catch (e: Exception) { println("Exception {e} while parsing {url}"); } finally { is.close(); 14 } } }
  • 15. Example: reading resources > Getting a JSON resource catalog onException: function (e: Exception) { imageURLs = "media/black_glossy_web20_icon_012.png"; urlsLoaded = true; } onDone: function() { images = for (url in imageURLs) { DeferredImage { url: url }; } imageURLs = null; urlsLoaded = true; } } request.start(); } return urlsLoaded; } def parseEventCallback = function (event: Event): Void { if ((event.type == PullParser.TEXT) and (event.name == "url")) { insert event.text into imageURLs; } 15 } }
  • 16. Example: reading resources > Loading an image > JavaFX Image loads automatically when initialized var imageCounter = 0; public class DeferredImage { public-init var url : String; public-read var progress = bind image.progress; public-read var error = bind image.error; def id = imageCounter++; public-read var image : Image; public function load() { // start loading only when load() is called if (image == null) { image = Image { url: url backgroundLoading: true } } } 16 }
  • 17. Example: binding > Introducing TaxonSearchController – Manages a list of Taxons – Produces a filtered list of Taxons whose names match a substring – Provides a hint for autocompletion  Eg. you type “He”  That matches only “Heron ***”  Hints is “Heron “ 17
  • 18. Example: binding > Some relevant parts of Taxon public class Taxon { public-read protected var displayName : String; public-read protected var scientificName : String; public-read protected var id : String; override function toString() { return "{displayName} ({scientificName}) ({id})" } } 18
  • 19. Example: binding > TaxonSearchController (1/3) public class TaxonSearchController { public var taxons: Taxon[]; public var filteredTaxons: Taxon[]; public var selectedTaxonIndex : Integer = -1; // set from the UI public var selectedTaxon = bind if (selectedTaxonIndex < 0) then null else filteredTaxons[selectedTaxonIndex]; // setting this property will trigger filtering public var filter = "" on replace { filteredTaxons = taxons[taxon | matches(taxon, filter)]; updateHint(); } public-read var hint = ""; // the auto-completed hint 19
  • 20. Example: binding > TaxonSearchController (2/3) protected function matches (taxon : Taxon, string: String) : Boolean { if (string == "") { return true; } if (taxon.displayName.toLowerCase().startsWith(string.toLowerCase())) { return true; // more complex in the real case, as it also deals with scientific name // but not relevant now } return false; } 20
  • 21. Example: binding > TaxonSearchController (3/3) protected function updateHint(): Void { def hintTry = commonLeadingSubstring(filteredTaxons); // // Sometimes it can't find a better auto-completion than the current filter, // hint = if (hintTry.length() > filter.length()) then hintTry else filter; } } 21
  • 22. Example: binding > TaxonSearchScreen public class TaxonSearchScreen extends Container // e.g. a UI panel { // warning: there are some simplifications, but the concepts are here public-read def controller = TaxonSearchController { selectedTaxonIndex: bind list.selectedIndex; } def list = ListBox { // the list widget in the UI items: bind controller.filteredTaxons }; def hint = bind controller.hint on replace { if (hint != "") { filter = hint; } } var resetSelectionWhenFilterChanges = bind controller.selectedTaxon on replace { if (controller.selectedTaxon != null) { list.selectedIndex = 0; } } TextBox { // a text input box in the UI text: bind controller.filter with inverse } Text { // a label rendering a text in the UI content: bind "{sizeof controller.filteredTaxons} specie(s)" 22 }
  • 23. JavaFX mobile in 2009 > Development tools available (emulator, etc...) > First capable phones at J1: LG Incite, HTC Touch Diamond > Announced a “JavaFX Mobile player” – Would run JavaFX on MSA (JSR 248) JME phones > Looked very promising – That's why blueBill Mobile started with it 23
  • 24. Status updates in 2010 > Barcelona Mobile World Congress 2010 – “Feature phones” (Qualcomm and the Brew Mobile Platform OS) – Sony-Ericsson in “upcoming phones” > Recent phone status update (JavaFX forums, March 16, 2010) – LG Incite, HTC Touch Diamond... still! – “Unofficially” runs on any Windows Mobile 6.x device (e.g. HTC HD2) > JavaFX 1.3 released on May 14, 2010 – Shares many improvements with the desktop/web profile – Mobile emulator runs on Mac OS X > JavaFX Mobile Player MIA (I mean, it's Windows Mobile only) > No further manufacturer endorsements? 24
  • 25. My view of Java-related mobile solutions > We're in the climax of the “next generation mobile” war – iPhone/iPad, Android leading on the growth rates – Adobe Flash at stake, but if it survives will be relevant > Is there still room for JavaFX Mobile? JME? > JavaFX Mobile – Still excites me, technically – The Oracle-Sun deal might have slowed down deals – but... – … timing out this Summer –Hoping in a specific Android port/adaptation (using the Android UI/runtime)  Hearing a few people talking about that  Would bring-in e.g. the integration with graphic designer workflow > JME still relevant for the “glorious old guard” (Nokia, etc..., BlackBerry) – “Oldies but goodies” 25
  • 26. My research for the Summer > Two/threefold strategy – Android (it delivers, short time-to-market) – JME (catch the “old glorious guard”) – JavaFX (if industry endorsements / Android support will show up) > Study whether it is possible to reuse code – Not thinking of “catch-all” frameworks – Reusing only the models, writing ad-hoc UIs (no “GCD syndrome”) – Maven for re-using artifacts – Byte-code manipulation (e.g. RetroWeaver) for fitting JME Java 1.3? – Follow my blog and my space at Dzone.com > The “new” blueBill Mobile for JavaFX code is not yet available – Under heavy refactoring, catching up with the Android version 26
  • 27. Questions? > Thanks for your attention – http://javafx.com – http://bluebill.tidalwave.it/mobile – http://windrose.tidalwave.it 27
  • 28. Fabrizio Giudici www.tidalwave.it Tidalwave s.a.s. fabrizio.giudici@ tidalwave.it