Mapping Directions with JavaFX using the GMapsFX Directions API

Mapping directions in a JavaFX application is easy with the Directions API that was recently introduced in GMapsFX.  In this blog post I’ll walk through an example of setting up an application with a map and a couple of text fields, one which will be used for the trip origin and the second which will be used for the trip destination.  When the user hits ‘Enter’ in the destination text field, the map will display the directions.

Starting off with the FXML file, we have an AnchorPane which contains the GoogleMapView and 2 TextFields.  The AnchorPane has a controller assigned to it named FXMLController, and both components have an FX ID associated with them so they will be accessible from the FXMLController class.  Also, the destination TextField has an action, “toTextFieldAction” associated with it, so this method will be called when the user hits the ‘Enter’ key in the TextField.

 

The result should look as follows:

Screen Shot 2016-08-19 at 2.56.27 PM

 

Next, I’ve cut up the relevant parts of the FXMLController class.  The MapComponentInitializedListener interface needs to be implemented by the controller since the underlying GoogleMap doesn’t get initialized immediately.  The DirectionsServiceCallback interface also needs to be implemented, although in this example I won’t be doing anything with it.

The GoogleMapView and the TextFields components from the FXML file are defined below and annotated with @FXML.

There is also a reference to the Directions Service as well as StringProperties to represent the ‘to’ and ‘from’ endpoints that the user will enter.

 

 

After the controller is created, its initialize method is called which will set the MapView’s initialization listener to the FXMLController as well as bind the ‘to’ and ‘from’ String properties to the TextProperties of their respective TextFields.

 

Once the map has been initialized, the DirectionService can be instantiated as well as a MapOptions object to set various attributes about the map.  The options are then configured and a GoogleMap object can be instantiated from the map view.  The directionsPane is a component which can be used to render the step by step direction text, in this example however, it won’t be displayed.

Finally, the action method defined in the FXML file when the user hits ‘Enter’ in the TextField is below.  The method will call the getRoute() method on the DirectionsService class, passing in a boolean value which will define whether the route can be modified by dragging it, the map object, and the DirectionsRequest object.

 

Below is an example when the user enters directions from Seattle to Redmond

 

Screen Shot 2016-08-19 at 3.37.38 PM

That’s it!  For completeness I’ll include the full source code of the example below.

 

 

Scene.fxml

 

MainApp.java

 

FXMLController.java

GMapsFX 2.0.9 Released

The latest version of GMapsFX has been released which contains a fix for a bug that was preventing the GoogleMapView component from being added as a custom component to SceneBuilder.

The fix will allow the MapView to be added as a custom component.  In a future blog post I will detail how to do this.

 

Screen Shot 2016-08-05 at 4.26.39 PM.png

Mapping an Address with JavaFX using the GMapsFX Geocoding API

Mapping an address in a JavaFX application is extremely easy with the Geocoding API that was recently introduced in GMapsFX.  In this blog post I’ll walk through an example of setting up an application with a map and a text field.  The map will recenter itself at whatever address or place the user types in the text field.

Starting off with the FXML file, we have an AnchorPane which contains the GoogleMapView and a TextField.  The AnchorPane has a controller assigned to it named FXMLController, and both components have an FX ID associated with them so they will be accessible from the FXMLController class.  Also, the TextField has an action, “addressTextFieldAction” associated with it, so this method will be called when the user hits the ‘Enter’ key in the TextField.

 

The result should look as follows:

Screen Shot 2016-07-29 at 3.12.18 PM.png

 

Next, I’ve cut up the relevant parts of the FXMLController class.  The MapComponentInitializedListener interface needs to be implemented by the controller since the underlying GoogleMap doesn’t get initialized immediately.  The GoogleMapView and TextField components from the FXML file are defined below and annotated with @FXML.

There is also a reference to the GeocodingService as well as a StringProperty to represent the address the user enters.

 

 

After the controller is created its initialize method is called which will set the MapView’s initialization listener to the FXMLController as well as bind the address property to the address TextField’s text property.

 

Once the map has been initialized, the GeocodingService can be instantiated as well as a MapOptions object to set various attributes about the map.  Once the options are configured, a GoogleMap object can be instantiated from the map view.

 

Finally, the action method defined in the FXML file when the user hits ‘Enter’ in the TextField is below.  The method will call the geocode() method on the GeocodeService class, passing in the value of the Address property as well as a callback method.

The callback will check the status of the results, and based on the outcome, will recenter the map at the latitude/longitude the user had entered.

 

Below is an example when the user enters New York City as the address.

Screen Shot 2016-07-29 at 4.27.56 PM

 

That’s it!  For completeness I’ll include the full source code of the example below.

 

 

Scene.fxml

 

MainApp.java

 

FXMLController.java

GMapsFX 2.0.7 Released

A new version of GMapsFX has been released to bintray and Maven Central.  The main feature in this version is to allow the use of custom marker/pin images, rather than relying on the default Google images.

A future blog post will demonstrate how to add custom markers to your GMapsFX application.

 

Screen Shot 2016-05-20 at 2.25.33 PM

 

GMapsFX 2.0.6 Released

A new version of GMapsFX has been released to bintray and Maven Central which contains

  • additional bug fixes related to hiding/showing the directions pane at runtime.
  • Ability to pass the map/directions language to the Google map at runtime, eliminating the need to hardcode it.

Screen Shot 2016-05-20 at 2.25.33 PM.png

<dependency> 
  <groupId>com.lynden</groupId> 
  <artifactId>GMapsFX</artifactId> 
  <version>2.0.6</version> 
</dependency>

 

GMapsFX Home: http://rterp.github.io/GMapsFX/
twitter: @RobTerpilowski

GMapsFX 2.0.4 Released

A minor update of GMapsFX has been released this week which provides a bugfix for an issue that was preventing the GMapsFX GoogleMapView component from being loaded into Scene Builder under certain circumstances.

The release number is 2.0.4 and is currently available from BinTray, and hopefully should be available via Maven Central in the next couple of days.

twitter: @RobTerpilowski
LinkedIn: RobTerpilowski

 

Screen Shot 2016-03-18 at 3.40.46 PM

 

 

GMapsFX 2.0.3 Released With Support for Directions, Elevation, and Geocoding APIs

I have just released version 2.0.3 which includes support for the following major new features:

Directions API
Elevation API
Geocoding API

http://rterp.github.io/GMapsFX/

Below is an example of a JavaFX application displaying a Google map with directions, utilizing the Directions API.

Screen Shot 2016-03-18 at 3.40.46 PM.png

This release has been uploaded to bintray, and should hopefully be available on maven central by next week.

Blog posts to follow this one with tutorials on how to use each one of these new APIs.

https://bintray.com/artifact/download/rterp/maven/com/lynden/GMapsFX/2.0.3/GMapsFX-2.0.3.jar

twitter: @RobTerpilowski
LinkedIn: RobTerpilowski

 

Freight Tracking with JavaFX and the NetBeans Rich Client Platform

iconI am super proud of my team who this week, rolled out Version 2.0 of Lynden Navigator to more than 1,000 desktops company-wide.   Navigator allows our freight terminal managers to optimize resource planning by giving them complete visibility to freight that is scheduled to arrive and depart to/from their facility.  In addition, customer service personnel have access to a new Shipment Tracing plugin included in this version which can be used to quickly access current information about customer freight and freight history.

The initial version of the application was built on the NetBeans Rich Client Platform (RCP), utilizing Swing UI components, but version 2.0 includes new functionality implemented with JavaFX.  A screenshot of the new version of Navigator appears below.  The top portion of the application is original portion that is utilizing Swing, and specifically components developed by JideSoft.   The lower portion of the screen is new functionality that has been built utilizing JavaFX.

FMS

Enter a caption

JavaFX Toolkit Not Initialized (Solved)

I am attempting to utilize the NetBeans Rich Client Platform (RCP) as a shell to manage plugins for an automated trading application which uses JavaFX for the UI, but no Swing components. As such, I have a module installer class which creates the JavaFX scene, but no TopComponent class which RCP developers are accustom to using. The module class I have created is below.

import org.openide.modules.ModuleInstall;

public class Installer extends ModuleInstall {

@Override
public void restored() {
    Platform.setImplicitExit(false);

    // create JavaFX scene
    Platform.runLater(() -> {
        Parent root;
        try {
            FXMLLoader fxmlLoader = new FXMLLoader(MainScreen.class.getResource("/com/zoicapital/qtrader/plugin/BasePanel.fxml"));
            root = (Parent) fxmlLoader.load();
            Scene scene = new Scene(root);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    });
}

The problem is that when launching the application the following exception is being thrown.

java.lang.IllegalStateException: Toolkit not initialized
at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:273)
at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:268)
at javafx.application.Platform.runLater(Platform.java:83)
at com.zoicapital.qtrader.plugin.Installer.restored(Installer.java:22)

It turns out that even though Platform.runLater() is being invoked, it does not initialize the JavaFX runtime if it hasn’t already been started.

There are a couple of ways around the issue. The first is to invoke the Application.launch() method, or simply instantiate a new JFXPanel() class (even if it isn’t used for anything). Either action will cause the JavaFX Runtime to start and avoid initialization exception when the application is started.

Make Money Online Automatically. Trading Commodities with JavaFX and the NetBeans Rich Client Platform

Ok, so maybe it isn’t quite as easy as it sounds, but we were able to leverage an automated trading application we had previously written and the modularity of the NetBeans Rich Client Platform to create a commodity trading application that will interface with, and allow us to place trades with a new commodity broker.

Even though the original application was for the purposes of automated trading, we were able to use many of the same NetBeans plugins we had developed in order to create the new application, as well as utilize JavaFX to put a nice polished UI on the app.

The login screen is below. The commodity images on the right side of the screen scroll down the UI and represent each commodity market that we trade.
enter image description here

After logging in to the application, those same commodities are in a dock at the top of the window. The images have an animated effect that will fade-in a green background when the mouse moves over the component. The first table in the UI shows orders that have been sent to the broker, but have not been fully executed, and the lower table displays commodity orders that have been completely executed.

enter image description here

After clicking on a commodity component at the top of the screen, the user is presented with a dialog to enter details about the order which will be placed. In the case of the screenshot below, an order is being entered to purchase 50 contracts of gold.

enter image description here

The last screenshot displays the state of the two main tables after orders to trade gold and natural gas have been fully executed, and while an order to purchase 50 Canadian Dollar futures contracts is still in process.

enter image description here

And finally, the 2 minute demo below highlights the application’s functionality as well as shows off the animated transitions and other eye candy that is possible using JavaFX. I will be speaking at JavaOne at a session entitled Flexibility Breeds Complexity: Living in a Modular World [CON6767], where I will discuss this and other JavaFX applications built on the NetBeans Rich Client Platform.

twitter: @RobTerpilowski

Written with StackEdit.