I have a project requiring the embedding of google maps in a desktop java application. I found after some research that Java FX does provide this functionality and proceeded to write a sample application as a PoC. the application worked and everything was fine. After upgrading to the new 7u7 java version, my code no longer works like it did before. The code runs and displays the web page, but no gesture (paning/ zooming) events are fired to the web page (google maps) and for some reason when i clikc and drag (as if to pan) i get the enclosed exception which i can make no sense of.
I would very much appreciate any insight someone might have in the emmbedding of Google Maps in a JavaFX 2.2 application. Thank you in advance for any help and/or suggestions
Following is my application code/HTML code and the exception thrown:
JavaFX code:
private Scene scene;
private MyBrowser myBrowser;
private LocationClickHandler handler;
private Vector<Button> buttons;
//private Moderator moderator;
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
buttons = new Vector<Button>();
//moderator = new Moderator();
handler=new LocationClickHandler();
primaryStage.setTitle("java-buddy.blogspot.com");
myBrowser = new MyBrowser();
//moderator.registerAddIconListener(myBrowser);
VBox mainbox = new VBox();
mainbox.getChildren().add(myBrowser);
// mainbox.getChildren().add(generateEntitiesButtonBox());
// mainbox.getChildren().add(generateSensorsButtonBox());
scene = new Scene(mainbox, 1280, 760);
primaryStage.setScene(scene);
primaryStage.show();
}
class MyBrowser extends Region {
HBox toolbar;
WebView webView = new WebView();
WebEngine webEngine = webView.getEngine();
public MyBrowser(){
webView.setMinSize(1280, 400);
final URL urlGoogleMaps = getClass().getResource("googlemaps2.html");
webEngine.load(urlGoogleMaps.toExternalForm());
getChildren().add(webView);
/*webEngine.getLoadWorker().stateProperty().addListener(
new ChangeListener<State>() {
@Override public void changed(ObservableValue<? extends State> ov, State oldState, State newState) {
if (newState == State.SUCCEEDED) {
JSObject win = (JSObject) webEngine.executeScript("window");
win.setMember("java", handler);
}
}
});*/
}
HTML loaded into the Web View:
<!DOCTYPE html>
<html>
<head>
<title>Java-Buddy: Google Maps</title>
<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
<style>#mapcanvas { height: 500px; width: 100%}</style>
<script type="text/javascript">
var map;
var icon="icons/Tank.png";
var last_clicked;
var elliptical=0;
var sensors = new Array();
var sensors_to_targets = new Array();
var targets = new Array();
var target_paths = new Array();
var target_polys = new Array();
var counter =0;
//var marker;
function loadmap(){
var options = {
zoom: 16,
center: new google.maps.LatLng(51.507222, -0.1275),
mapTypeId: google.maps.MapTypeId.SATELLITE,
streetViewControl: false
}
map = new google.maps.Map(document.getElementById("mapcanvas"), options);
google.maps.event.trigger(map,'resize');
google.maps.event.addListener(map, 'click', function(event) {
java.saveLocation(event.latLng.lat(),event.latLng.lng());
});
}
</script>
</head>
<body onload="loadmap()">
<div id="mapcanvas"></div>
</body>
</html>
exception thrown when dragging in the web view:
java.lang.NullPointerException: Clipboard.putContent: null data
at com.sun.javafx.tk.quantum.QuantumClipboard.putContent(QuantumClipboard.java:442)
at javafx.scene.input.Clipboard.setContent(Clipboard.java:226)
at com.sun.webpane.sg.UIClientImpl.confirmStartDrag(UIClientImpl.java:178)
at com.sun.webpane.platform.WebPage.confirmStartDrag(WebPage.java:861)
at javafx.scene.web.WebView$19.handle(WebView.java:1204)
at javafx.scene.web.WebView$19.handle(WebView.java:1201)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:69)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:217)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:170)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:38)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:37)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:53)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:33)
at javafx.event.Event.fireEvent(Event.java:171)
at javafx.scene.Scene$DnDGesture.fireEvent(Scene.java:2627)
at javafx.scene.Scene$DnDGesture.process(Scene.java:2706)
at javafx.scene.Scene$DnDGesture.access$8700(Scene.java:2603)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3340)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3164)
at javafx.scene.Scene$MouseHandler.access$1900(Scene.java:3119)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1559)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2261)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:228)
at com.sun.glass.ui.View.handleMouseEvent(View.java:528)
at com.sun.glass.ui.View.notifyMouse(View.java:922)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:29)
at com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:73)
at java.lang.Thread.run(Unknown Source)
This looks like a bug in WebView, I'll file it.
As a workaround you can provide an empty drag handler to your WebView:
Based on the issue Sergey linked, it seems one part of this issue is caused by an error in Google Maps v3 api and is a result of enabling touch events in the browser (panning doesn't work with Google Maps v3 api in Chrome with touch events enabled either).
JavaFX 2.0.x (and 2.1.x) webview did not have touch events implemented, but JavaFX 2.2 does, hence one reason for the difference in behaviour between the two.
As a work around you could use v2 of the google maps api which don't feature this bug (well at least until that version of the api goes offline on May 19, 2013). Or you can use JavaFX 2.1 until the JavaFX team and Google implement a fix/workaround. Or you can continue seeking other workarounds such as that suggested by Sergey or variation thereof which works for you.