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.
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 10:48 AM EDT #
need more about java
Posted by vijipari on July 20, 2008 at 02:37 AM EDT #