JavaFX Script and JSON Weather service

Brian Goetz recently completed the JavaFX script class "javafx.async.AsyncJsonCall" that allows one to issue a JSON webservice call in the background. Once the call is complete, a call back function "onDone" is called that indicates whether or not the call succeeded. This blog includes an example of how this JSON call might be done.

I decided to use the GeoNames JSON webservices and more particularily the "Weather Station with most recent weather observation". This service provides the current weather conditions at the particular weather station provided. The weather station is identified by the International Civil Aviation Organization (ICAO) code. Typically, in the US, this code is the letter 'K' followed by the more popular IATA code for the airport. For example, JFK international in New York has an IATA code of "JFK" so the ICAO code is KJFK. In the example below, I used my home airport of Orlando, Florida USA which has the ICAO code, "KMCO".

Click here for more details on on the GEO Names JSON Web Services and for the ICAO codes. For more information on the JSON grammar, check out www.json.org.

First, I declare a variable to hold the URL to the GEONames Web Service. Just to keep things simple for now I have hard coded in the ICAO code for Orlando, "KMCO".

"http://ws.geonames.org/weatherIcaoJSON?ICAO=KMCO"; 
Then, I declare an object to hold the values from the JSON Object that is returned. For now, I have to manually populate this object within my code, but eventually there will be mechanism in the JavaFX Script JSON framework to do this automatically.

Next, I declare the "AsyncJsonCall" object literal, passing in the "url", and providing a function implementation for the "onDone" attribute. "onDone" will be called once the call is completed and the "success" boolean parameter indicates whether it succeeded or not. If it failed,  the attribute "failureText" inside the "AsyncJsonCall" object will contain a string describing the failure.
If the call succeeds, then the "document" attribute  from the "AsyncJsonCall" object will contain the top level javafx.json.JSONObject. From this object,  I fetch the "weatherObservation" object, and from that, fetch all the members for my "weather" class.

To show the power of JavaFX Script binding, I draw a simple Frame, and output the members of my weather object. Because "AsyncJsonCall" runs in the background, there may be a delay before the actual data is displayed. Using the JavaFX binding feature, I bound the members of my "weather" object to the "Text" gui nodes, so that when the "weather" object eventually is populated, the screen will update automatically.

An example of the JSON Object that is returned:

{
  "weatherObservation":
    {
      "clouds":"scattered clouds",
      "weatherCondition":"n/a",
      "observation":"KMCO 171753Z 27010KT 10SM SCT045 SCT055 BKN140 BKN250 32/19 A2993 RMK AO2 SLP133 T03220189 10322 2024
4 58018",
      "windDirection":270,
      "ICAO":"KMCO",
      "seaLevelPressure":1013.3,
      "elevation":29,
      "countryCode":"US",
      "lng":-81.3333333333333,
      "temperature":"32.2",
      "dewPoint":"18.9",
      "windSpeed":"10",
      "humidity":45,
      "stationName":"Orlando, Orlando International Airport",
      "datetime":"2008-06-17 17:53:00",
      "lat":28.4166666666667
    }
}

The JavaFX Code to process the JSON Object returned from the JSON Weather Service:

 =============================

import javafx.async.\*;
import javafx.json.\*;
import java.net.URL;
import java.lang.System;
import javafx.gui.\*;

// ICAO code in US is typically 'K' + IATA airport code
// MCO is Orlando FL US IATA code, so ICAO is KMCO.
// New York - JFK is KJFK.
// See http://en.wikipedia.org/wiki/List_of_airports_by_ICAO_code
var url = "http://ws.geonames.org/weatherIcaoJSON?ICAO=KMCO";

class Weather {
    public attribute station:String;
    public attribute clouds:String;
    public attribute windDirection:Number;
    public attribute windSpeed:Number;
    public attribute temperature:Number;
    public attribute dewPoint:Number;
    public attribute humidity:Number;
    public attribute observation:String;
}
var weather:Weather = Weather{};
var call:AsyncJsonCall;
call = AsyncJsonCall{
    url: url 
    onDone: function(success : Boolean) : Void {
        System.out.println("JSON Call is done: result = {success}");
        if(success) {
            var json = call.document;
            var observation = json.getValue("weatherObservation") as JSONObject;
            var pair:Pair;
            weather.station = '{observation.getValue("stationName")}';
            weather.clouds = '{observation.getValue("clouds")}';
            weather.windDirection = observation.getPair("windDirection").getValueAsNumber();
            weather.windSpeed = observation.getPair("windSpeed").getValueAsNumber();
            weather.temperature = observation.getPair("temperature").getValueAsNumber();
            weather.dewPoint = observation.getPair("dewPoint").getValueAsNumber();
            weather.humidity = observation.getPair("humidity").getValueAsNumber();
            weather.observation = '{observation.getValue("observation")}';
        }else {
            System.out.println("failure = {call.failureText}");
        }
    }
}

Frame {
    title: "JSON Weather";
    closeAction: function() { java.lang.System.exit(0); }
    visible: true
    width: 500
    height: 500
    content: Canvas {
        content: VBox {
            spacing: 10
            content: [
                HBox {
                    content: [
                        Text {translateX:10 translateY:10 content: "Station:"},
                        Text {
                            translateX:10 
                            translateY:10 
                            content: bind weather.station 
                            fill: Color.BLUE
                        }
                    ]
                },
                HBox {
                    content: [
                        Text {translateX:10 translateY:10 content: "Clouds:"},
                        Text {
                            translateX:10 
                            translateY:10 
                            content: bind weather.clouds 
                            fill: Color.BLUE
                        }
                    ]
                }, 
                HBox {
                    content: [
                        Text {translateX:10 translateY:10 content: "Wind Direction:"},
                        Text {
                            translateX:10 
                            translateY:10 
                            content: bind "{weather.windDirection} degrees" 
                            fill: Color.BLUE}
                    ]
                },
                HBox {
                    content: [
                        Text {translateX:10 translateY:10 content: "Wind Speed:"},
                        Text {
                            translateX:10 
                            translateY:10 
                            content: bind "{weather.windSpeed} knots" 
                            fill: Color.BLUE}
                    ]
                }, 
                HBox {
                    content: [
                        Text {translateX:10 translateY:10 content: "Temperature:"},
                        Text {
                            translateX:10 
                            translateY:10 
                            content: bind "{weather.temperature}C degrees" 
                            fill: Color.BLUE}
                    ]
                }, 
                                HBox {
                    content: [
                        Text {translateX:10 translateY:10 content: "Dew Point:"},
                        Text {
                            translateX:10 
                            translateY:10 
                            content: bind "{weather.dewPoint}C degrees" 
                            fill: Color.BLUE}
                    ]
                }, 
                HBox {
                    content: [
                        Text {translateX:10 translateY:10 content: "Humidity:"},
                        Text {
                            translateX:10 
                            translateY:10 
                            content: bind "{weather.humidity}%" 
                            fill: Color.BLUE}
                    ]
                }, 
                HBox {
                    content: [
                        Text {translateX:10 translateY:10 content: "METAR Observation:"},
                        Text {
                            translateX:10 
                            translateY:10 
                            content: bind "{weather.observation}" 
                            fill: Color.RED}
                    ]
                },                 
            ]
        }
    }
    
}

=============================

There are a few other features of the  "javafx.async.AsyncJsonCall"  class that are useful, like showing the progress of the webservice call.  I will demonstrate these in a future blog post.


        
    
Comments:

This is a great example. Could you include a screenshot of what the final application looks like? Thanks!

Posted by Josh Marinacci on June 20, 2008 at 03:48 AM EDT #

need more about java

Posted by vijipari on July 19, 2008 at 07:37 PM EDT #

There is a json weather service
http://mrlu.host22.com/weather.php?callback=cb
it's return value is
cb({....})

Posted by jason on July 08, 2009 at 08:25 AM EDT #

Hi Jim
Thanks for the book - That is awesome!!! You've obviously become the programmer extraordinaire
I'm proud of you
From your older bro
Jerry

Posted by Jerry Clarke on July 15, 2009 at 06:17 AM EDT #

Working JavaFX examples for JSON, RSS, Google API, Yahoo API
- http://jfxstudio.wordpress.com/2009/07/24/javafx-web-services/

Posted by surikov on July 24, 2009 at 02:37 AM EDT #

OFF Topic ...

FYI, your NASA image browser JavaFX example works fine in Mac OS X Snow Leopard
java version "1.6.0_15"
Java(TM) SE Runtime Environment (build 1.6.0_15-b03-219)
Java HotSpot(TM) 64-Bit Server VM (build 14.1-b02-90, mixed mode)

Posted by Mike Rainville on September 24, 2009 at 04:40 PM EDT #

Post a Comment:
  • HTML Syntax: NOT allowed
About

jimclarke

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today