GMapsFX :: Add Google Maps to your JavaFX application.

We have been considering adding a map component to our Freight Management application built on the NetBeans RCP and JavaFX, which would allow Lynden dispatchers to track its drivers throughout the city as well as highlight where trailers have been dropped off at customer locations and are ready for pickup.

Google Maps is a logical tool which could be utilized to accomplish this task. While there are examples out on the web for integrating Google Maps with JavaFX, these solutions require mingling JavaScript within the Java code in order to interact with a Google Map loaded within the application.

In an effort to remove the need to code JavaScript within JavaFX in order to use Google Maps, I have created a Java API ‘wrapper’ around the Google Maps JavaScript API and have dubbed this framework GMapsFX. This allows one to add a Google Map component to a JavaFX application and interact with it utilizing a pure Java API.

While at the present time only the most basic Google Map functionality has been ‘wrapped’ by the Java API, I am making this project open source in the hopes that if others find this library useful and require additional functionality, that it could be added and contributed back to the community.

Hi Clayn,
The library is basically a WebView wrapper around the Javascript API, so it is not making any additional calls than if you were running the Google Maps API in a browser based application with Javascript.

Provided code sample issues the following stack trace :
netscape.javascript.JSException: ReferenceError: Can’t find variable: google
at com.sun.webkit.dom.JSObject.fwkMakeException(JSObject.java:128)
at com.sun.webkit.WebPage.twkExecuteScript(Native Method)
at com.sun.webkit.WebPage.executeScript(WebPage.java:1410)
at javafx.scene.web.WebEngine.executeScript(WebEngine.java:934)
at com.lynden.gmapsfx.javascript.JavaFxWebEngine.executeScript(JavaFxWebEngine.java:39)
at com.lynden.gmapsfx.javascript.JavascriptRuntime.execute(JavascriptRuntime.java:64)
at com.lynden.gmapsfx.javascript.JavascriptObject.(JavascriptObject.java:49)
at com.lynden.gmapsfx.javascript.object.LatLong.(LatLong.java:36)
at application.Sample.mapInitialized(Sample.java:45)
at com.lynden.gmapsfx.GoogleMapView.fireMapInitializedListeners(GoogleMapView.java:132)
at com.lynden.gmapsfx.GoogleMapView$1.changed(GoogleMapView.java:74)
at com.lynden.gmapsfx.GoogleMapView$1.changed(GoogleMapView.java:61)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:176)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
at javafx.beans.property.ReadOnlyObjectWrapper$ReadOnlyPropertyImpl.fireValueChangedEvent(ReadOnlyObjectWrapper.java:176)
at javafx.beans.property.ReadOnlyObjectWrapper.fireValueChangedEvent(ReadOnlyObjectWrapper.java:142)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:145)
at javafx.scene.web.WebEngine$LoadWorker.updateState(WebEngine.java:1214)
at javafx.scene.web.WebEngine$LoadWorker.dispatchLoadEvent(WebEngine.java:1325)
at javafx.scene.web.WebEngine$LoadWorker.access$1100(WebEngine.java:1207)
at javafx.scene.web.WebEngine$PageLoadListener.dispatchLoadEvent(WebEngine.java:1194)
at com.sun.webkit.WebPage.fireLoadEvent(WebPage.java:2373)
at com.sun.webkit.WebPage.fwkFireLoadEvent(WebPage.java:2217)
at com.sun.webkit.network.URLLoader.twkDidFail(Native Method)
at com.sun.webkit.network.URLLoader.notifyDidFail(URLLoader.java:842)
at com.sun.webkit.network.URLLoader.access$1300(URLLoader.java:43)
at com.sun.webkit.network.URLLoader$7.run(URLLoader.java:824)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$300(WinApplication.java:39)
at com.sun.glass.ui.win.WinApplication$4$1.run(WinApplication.java:112)
at java.lang.Thread.run(Thread.java:745)

The problem comes with the line 114 in the MainApp sample:
LatLong center = new LatLong(47.606189, -122.335842);
This line executes the following javascript :
var LatLong0 = new google.maps.LatLng(47.606189,-122.335842)

Got this exception several times. Figured out it happens when i try to use something that uses the webeninge (in my cases for example “new LatLng()”) when the GoogleMapView wasnt initialized yet. So i think you should wait for such things until “mapInitialized” was called.
Maybe this works for you

Yes, that is exactly what the example is doing? The LatLong objects are being initialized in the mapInitialized callback method. The strange thing is that I can’t seem to replicate this issue. I’m downloading Eclipse now, to see if I can replicate it there, but I’ve tried the example app on a few different machines with different OSs, but haven’t had any luck.

Hi! I have received the same error as Jean-Pascal (netscape.javascript.JSException: ReferenceError: Can’t find variable: google), i have tried it with GMapsFX-1.1.1.jar y con GMapsFX-1.1.0.jar but i haven’t get nothing.
I’ll agree you alot if you’d say us how to solve it.
Thank you very much.

netscape.javascript.JSException: RangeError: Maximum call stack size exceeded.
at com.sun.webkit.dom.JSObject.fwkMakeException(JSObject.java:128)
at com.sun.webkit.dom.JSObject.fwkMakeException(JSObject.java:128)
at com.sun.webkit.WebPage.twkExecuteScript(Native Method)
at com.sun.webkit.WebPage.executeScript(WebPage.java:1410)
at javafx.scene.web.WebEngine.executeScript(WebEngine.java:934)
at com.lynden.gmapsfx.javascript.JavaFxWebEngine.executeScript(JavaFxWebEngine.java:39)
at com.lynden.gmapsfx.GoogleMapView.mapResized(GoogleMapView.java:101)
at com.lynden.gmapsfx.GoogleMapView.lambda$createMap$19(GoogleMapView.java:127)
at com.lynden.gmapsfx.GoogleMapView$$Lambda$6/33095720.handle(Unknown Source)
at com.lynden.gmapsfx.javascript.event.EventHandlers.handleStateEvent(EventHandlers.java:107)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at com.sun.webkit.Utilities$1.run(Utilities.java:75)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.webkit.Utilities.fwkInvokeWithContext(Utilities.java:72)
at com.sun.webkit.Timer.twkFireTimerEvent(Native Method)
at com.sun.webkit.Timer.fireTimerEvent(Timer.java:66)
at com.sun.webkit.Timer.notifyTick(Timer.java:47)
at javafx.scene.web.WebEngine$PulseTimer$2.pulse(WebEngine.java:1154)
at com.sun.javafx.tk.Toolkit$3.run(Toolkit.java:321)
at com.sun.javafx.tk.Toolkit$3.run(Toolkit.java:319)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:319)
at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:348)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:479)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:460)
at com.sun.javafx.tk.quantum.QuantumToolkit$13.run(QuantumToolkit.java:327)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$300(WinApplication.java:39)
at com.sun.glass.ui.win.WinApplication$4$1.run(WinApplication.java:112)
at java.lang.Thread.run(Thread.java:745)

I guess it is when trying to put the mark on the map cause it is not showing up

I could not, I tried everything, absolute path, relative path. Only if I place image somewhere in the GMapsFX library – it works. The path should be relative to the maps.html file location.
I could not find solution how to point application to icon next to my Jar or images/ folder for example

I have a similar project using google maps with javafx and i´ve had a problem with the map, the map is too slow to use comparing with google map running in a browser, with zoom in/out, hybrid map, anything you need to do many times like zoom in/out. I donwloaded this project and realized it´s occured too, searching on web i found a post saying that it occurs because javafx webview doesn´t have cache like a browser, is it true ? is there any way to solve this problem ?

Where do I put in my Google API key? When I run this, I get
Caused by: java.lang.IllegalStateException: Couldn’t load map file ‘/html/maps.html’: NullPointerException
at com.lynden.gmapsfx.GoogleMapView.(GoogleMapView.java:162)
What goes in this file?