JavaFX 2.0 beta sample application and after thoughts

I had quite sometime back played around with JavaFX and had good and bad experiences using the language. With the JavaFX 2.0 beta being released I thought of giving it a try.

Here, I developed a simple Geocoding application which will take the address and provides the latitude-longitude values for that location – using Google Geocoding API.

I used Groovy for the JSON parsing, as the latest version-1.8 provides a really neat json parsing support.

import groovy.json.*
 
class GeocodingParser {
  static def GEOCODE_JSON_URL = "http://maps.googleapis.com/maps/api/geocode/json"
  static def GEOCODE_XML_URL = "http://maps.googleapis.com/maps/api/geocode/xml"
 
  static def getGeocodeForAddress(address){
    def queryBuilder = []
    queryBuilder << "address=${URLEncoder.encode(address)}"
    queryBuilder << "sensor=false"
    def queryString = queryBuilder.join("&")
    def requestUrl = GEOCODE_JSON_URL+"?${queryString}"
    def payload = new URL(requestUrl).text
    def jsonSlurper = new JsonSlurper()
    def doc = jsonSlurper.parseText(payload)
    def geocode = new Geocode()
    geocode.latitude = doc.results.geometry.location.lat.join("")
    geocode.longitude = doc.results.geometry.location.lng.join("")
    geocode.locationType = doc.results.geometry.location_type.join("")
    return geocode
  }
}
 
class Geocode {
  def String latitude
  def String longitude
  def String locationType
  def String toString(){
    return "Latitude: ${latitude}, Longitude:${longitude} and Location type: ${locationType}"
  }
}

You can see that the json parsing using JsonSlurper is so succinct. The groovy parser returns the latitude, longitude and location type (these are the values of interest for our application) values in the Geocode wrapper class – which is again a Grooy bean.

Now lets look at the JavaFX code which actually is the crux of this post:

public class NewFXMain extends Application {
 
 /**
 * @param args the command line arguments
 */
 public static void main(String[] args) {
   Application.launch(NewFXMain.class, args);
 }
 
 @Override
 public void start(Stage primaryStage) {
   primaryStage.setTitle("Geocoder");
   TabPane mainTabPane = new TabPane();
   Tab geoTab = new Tab("Geocoding");
   geoTab.setClosable(false);
   mainTabPane.getTabs().add(geoTab);
 
   final GridPane geoGrid = new GridPane();
   geoGrid.setHgap(10);
   geoGrid.setVgap(10);
   geoGrid.setPadding(new Insets(0, 20, 0, 10));
 
   Label mainGeoLabel = new Label("Geocoding");
 
   final TextBox geoAddressTextBox = new TextBox(15);
 
   Button geoCodeButton = new Button("Geocode");
   final TextBox latitudeValTextBox = new TextBox();
   latitudeValTextBox.setEditable(false);
   final TextBox longitudeValTextBox = new TextBox();
   longitudeValTextBox.setEditable(false);
   final TextBox locationTypeValTextBox = new TextBox();
   locationTypeValTextBox.setEditable(false);
 
   final StringProperty latitudeProperty = new StringProperty();
   latitudeProperty.addListener(new ChangeListener<String>() {
 
     @Override
     public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
       latitudeValTextBox.setText(newValue);
     }
   });
 
   final StringProperty longitudeProperty = new StringProperty();
   longitudeProperty.addListener(new ChangeListener<String>() {
 
     @Override
     public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
       longitudeValTextBox.setText(newValue);
     }
   });
 
   final StringProperty locationTypeProperty = new StringProperty();
   locationTypeProperty.addListener(new ChangeListener<String>() {
 
     @Override
     public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
       locationTypeValTextBox.setText(newValue);
     }
   });
 
   geoCodeButton.setOnAction(new EventHandler<ActionEvent>(){
 
     @Override
     public void handle(ActionEvent event) {
       String address = geoAddressTextBox.getText();
       if(address == null){
       }else{
         Geocode parsedCode = (Geocode)GeocodingParser.getGeocodeForAddress(address);
         latitudeProperty.set(parsedCode.getLatitude());
         longitudeProperty.set(parsedCode.getLongitude());
         locationTypeProperty.set(parsedCode.getLocationType());
      }
    }
   });
 
   geoGrid.add(mainGeoLabel, 4, 1);
   geoGrid.add(new Label("Address"), 2, 3);
   geoGrid.add(geoAddressTextBox, 3, 3,3,1);
   geoGrid.add(new Label("Latitude"), 2,7);
 
   geoGrid.add(new Label("Longitude"),2,8);
 
   geoGrid.add(new Label("Location Type"),2,9);
   geoGrid.add(latitudeValTextBox,3,7,2,1);
   geoGrid.add(longitudeValTextBox,3,8,2,1);
   geoGrid.add(locationTypeValTextBox,3,9,2,1);
   geoGrid.add(geoCodeButton, 4, 5);
   geoTab.setContent(geoGrid);
   Scene scene = new Scene(mainTabPane);
   primaryStage.setScene(scene);
   primaryStage.setVisible(true);
   primaryStage.setResizable(false);
 }
}

I have used bindings to bind the component displaying the latitude, longitude and location type values with the properties for the same values. For example, the code below shows how the latitude value was bound to the control which will display the value. This control (textbox) holds the latitude value obtained after passing the json response sent by the Geocoding API.

Now we create a StringProperty to hold the value for the latitude and we attach a change listener to this property such that when ever the value gets updated in the property we update the textbox with the new value. So, what exactly is changing the value of this property? We add a button which invokes the groovy parser and gets the latitude, longitude and location type values in a wrapper class. In the above action listener we get the parsed values and then update the properties with the corresponding values. This update in turn triggers the method in the corresponding change listeners.

Now coming to the layout for the controls. I used a GridBox layout and this was really flexible as it allowed me to place the components in a neat order.

Here are a few after thoughts:

  • JavaFX 2.0 has been changed to make more Java programmer friendly
  • JavaFX 2.0 more verbose than the JavaFX script- for example: looking at the way bindings has to be done.
  • Lack of tooling support – Creating a GUI is difficult.
  • Java programmers need not learn a new language all together, they wold feel at home with JavaFX APIs
  • Interoperability with other JVM languages like Groovy, Scala.
  • Lot of new controls, APIs added in the JavaFX 2.0.
  • Lack of multi-platform support.

The source code can be found here.

Reference: Sample application using JavaFX 2.0 beta and the after thoughts from our JCG partner Mohamed Sanaulla at the Experiences Unlimited Blog.

Related Articles :
Related Whitepaper:

Java Essential Training

Author David Gassner explores Java SE (Standard Edition), the language used to build mobile apps for Android devices, enterprise server applications, and more!

The course demonstrates how to install both Java and the Eclipse IDE and dives into the particulars of programming. The course also explains the fundamentals of Java, from creating simple variables, assigning values, and declaring methods to working with strings, arrays, and subclasses; reading and writing to text files; and implementing object oriented programming concepts. Exercise files are included with the course.

Get it Now!  

Leave a Reply


five × 4 =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

15,153 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books