
рдореИрдВ JavaFX рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ Google рдореИрдкреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдиреЗ рдЕрдиреБрднрд╡ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рдПрдХ рдирдХреНрд╢реЗ рдХреЛ рдПрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рд▓реЛрдб рдХрд░рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдФрд░ рдЕрдкрдиреЗ рдЬрд╛рд╡рд╛ рдХреЛрдб рд╕реЗ рд▓реЛрдб рдХрд┐рдП рдЧрдП рдирдХреНрд╢реЗ рдХреЗ рд▓рд┐рдП Google рдореИрдкреНрд╕ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдПрдкреАрдЖрдИ v3 рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВред
рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдореИрдк рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдХреЛрдб рд▓рд┐рдЦреЗрдВрдЧреЗ, рдЬрд┐рд╕реЗ рд╣рдо html рдкреЗрдЬ map.html рдХреЗ рд░реВрдк рдореЗрдВ рдбрд┐рдЬрд╛рдЗрди рдХрд░реЗрдВрдЧреЗред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЬреИрд╕реЗ рд╣реА рд╣рдо рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВ, рд╣рдо рдЕрддрд┐рд░рд┐рдХреНрдд рдХреЛрдб рдЬреЛрдбрд╝реЗрдВрдЧреЗред
map.html<!DOCTYPE html> <html> <head> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <style type="text/css"> html { height: 100% } body { height: 100%; margin: 0; padding: 0 } #map_canvas { height: 100% } </style> <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=***&sensor=false"> </script> <script type="text/javascript"> var map; var marker; function initialize() { var defLatLng = new google.maps.LatLng(59.95632093391832, 30.309906005859375); var mapOptions = { center: defLatLng, zoom: 3, mapTypeId: google.maps.MapTypeId.ROADMAP, disableDefaultUI: true, panControl: false }; map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions); marker = new google.maps.Marker({ position: defLatLng, map: map, icon: "img/Pin.png" }); } </script> </head> <body onload="initialize()"> <div id="map_canvas" style="width:100%; height:100%"></div> </body> </html>
рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдорд╛рдирдЪрд┐рддреНрд░ рдХреЗ рд╕рд╛рде рдПрдХ html рдкреГрд╖реНрда рд╣реИред рдЗрд╕реЗ рдХрд┐рд╕реА рднреА рдмреНрд░рд╛рдЙрдЬрд░ рдореЗрдВ рдЦреЛрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред JavaFX рдХреЗ рдкрд╛рд╕ рд╡реЗрдм рд╕рд╛рдордЧреНрд░реА рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдорд╣рд╛рди рд╡рд░реНрдЧ рд╣реИ: javafx.scene.web.WebViewред рд╣рдо рдЗрд╕рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рд▓рд┐рдЦрд┐рдд HTML рдкреЗрдЬ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░реЗрдВрдЧреЗред рдЪрд▓рд┐рдП GoogleMap рдХреНрд▓рд╛рд╕ рд▓рд┐рдЦрддреЗ рд╣реИрдВ рдЬреЛ рд╣рдорд╛рд░реЗ JavaFX рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ Google рдореИрдк рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░реЗрдЧрд╛ред рдХрд┐рд╕реА рдЕрдиреНрдп JavaFX рдиреЛрдб (рджреГрд╢реНрдп рдЧреНрд░рд╛рдл рдиреЛрдб) рдХреЗ рд╕рд╛рде рдорд╛рдирдЪрд┐рддреНрд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо javafx.scene.Parent рд╡рд░реНрдЧ рд╕реЗ рд╡рд╛рд░рд┐рд╕ рдХрд░реЗрдВрдЧреЗред
GoogleMap.java public class GoogleMap extends Parent { public GoogleMap() { initMap(); getChildren().add(webView); } private void initMap() { webView = new WebView(); webEngine = webView.getEngine(); webEngine.load(getClass().getResource("map.html").toExternalForm()); ready = false; webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() { @Override public void changed(final ObservableValue<? extends Worker.State> observableValue, final Worker.State oldState, final Worker.State newState) { if (newState == Worker.State.SUCCEEDED) { ready = true; } } }); } private WebView webView; private WebEngine webEngine; private boolean ready; }
рдХреЗрд╡рд▓ рдорд╛рдирдЪрд┐рддреНрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдирд╛ рд╣реА рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИред рд╣рдо рдорд╛рдирдЪрд┐рддреНрд░ рдХрд╛ рдкреНрд░рдмрдВрдзрди рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдФрд░ рдорд╛рдирдЪрд┐рддреНрд░ рдШрдЯрдирд╛рдУрдВ рдХреЛ рдкрдХрдбрд╝рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдлрд╝рдВрдХреНрд╢рдВрд╕ рддрдХ рдкрд╣реБрдБрдЪрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ netscape.javascript.JSObject рдХреНрд▓рд╛рд╕ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдЪрд╛рд╣рд┐рдП, рдЬреЛ рд╣рдореЗрдВ initCommunication () рд╡рд┐рдзрд┐ рдореЗрдВ рдорд┐рд▓рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ GoogleMap рдХреНрд▓рд╛рд╕ рдХреЗ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рд╡рд┐рдзрд┐ рдореЗрдВ рднреА, рд╣рдо GoogleMap.this рдХреЛрдб (GoogleMap рдХрдХреНрд╖рд╛ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг) рдХреЛ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕рдВрджрд░реНрдн рдореЗрдВ рдЫреЛрдбрд╝ рджреЗрдВрдЧреЗ, рдЬреЛ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛрдб рд╕реЗ GoogleMap рд╡рд░реНрдЧ рдХреЗ рддрд░реАрдХреЛрдВ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдЧрд╛ред
initCommunication () private void initCommunication() { webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() { @Override public void changed(final ObservableValue<? extends Worker.State> observableValue, final Worker.State oldState, final Worker.State newState) { if (newState == Worker.State.SUCCEEDED) { doc = (JSObject) webEngine.executeScript("window"); doc.setMember("app", GoogleMap.this); } } }); } private JSObject doc;
рдЪрд▓реЛ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛрдб рд╕реЗ рдЬрд╛рд╡рд╛ рдХреЛрдб рдХреА рдХреЙрд▓ рдХреЛ рдорд╛рдирдЪрд┐рддреНрд░ рдкрд░ рдПрдХ рдХреНрд▓рд┐рдХ рдХреА рдШрдЯрдирд╛ рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдЕрдЬреАрдм рд▓рдЧ рд╕рдХрддрд╛ рд╣реИ, рдпрд╣ рдШрдЯрдирд╛ рддрдм рд╣реЛрддреА рд╣реИ рдЬрдм рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрд┐рд╕реА рдорд╛рдирдЪрд┐рддреНрд░ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдореЗрдВ рдХреНрд▓рд┐рдХ рдХреЗ рднреМрдЧреЛрд▓рд┐рдХ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рд╣реЛрддреЗ рд╣реИрдВред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рд╣рдо рдИрд╡реЗрдВрдЯ рдХреНрд▓рд╛рд╕ рд▓рд┐рдЦрддреЗ рд╣реИрдВ:
MapEvent.java public class MapEvent extends Event { public MapEvent(GoogleMap map, double lat, double lng) { super(map, Event.NULL_SOURCE_TARGET, Event.ANY); this.lat = lat; this.lng = lng; } public double getLat() { return this.lat; } public double getLng() { return this.lng; } private double lat; private double lng; }
рдЕрдм рд╣рдо рд╣реИрдВрдбрд▓рд░ рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░рдиреЗ, рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛрдб рд╕реЗ рдШрдЯрдирд╛ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдФрд░ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ GoogleMap рд╡рд░реНрдЧ рдХреЗ рддрд░реАрдХреЛрдВ рдХреЛ рд▓рд┐рдЦреЗрдВрдЧреЗ:
GoogleMap рдХрдХреНрд╖рд╛ рд╡рд┐рдзрд┐рдпрд╛рдБ public void setOnMapLatLngChanged(EventHandler<MapEvent> eventHandler) { onMapLatLngChanged = eventHandler; } public void handle(double lat, double lng) { if(onMapLatLngChanged != null) { MapEvent event = new MapEvent(this, lat, lng); onMapLatLngChanged.handle(event); } } private EventHandler<MapEvent> onMapLatLngChanged;
рдпрд╣ рдХреЗрд╡рд▓ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛрдб рдореЗрдВ рдПрдХ рдорд╛рдирдЪрд┐рддреНрд░ рдИрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рд▓рд┐рдЦрдиреЗ рдФрд░ рдЙрд╕рдореЗрдВ GoogleMap рдХрдХреНрд╖рд╛ рдХреЗ рд╣реИрдВрдбрд▓ (рдбрдмрд▓ рд▓реЗрдЯ, рдбрдмрд▓ рд▓реИрдВрдЧ) рдкрджреНрдзрддрд┐ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛ рд╣реБрдЖ рд╣реИ:
get_click_position (рдШрдЯрдирд╛) function get_click_position(event){ var location = event.latLng; var lat = location.lat(); var lng = location.lng(); app.handle(lat, lng); }
рдЕрдм рд╣рдо рдЬрд╛рд╡рд╛ рдХреЛрдб рд╕реЗ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ GoogleMap рдХреНрд▓рд╛рд╕ рд╡рд┐рдзрд┐ рд▓рд┐рдЦреЗрдВрдЧреЗ
invokeJS (рдЕрдВрддрд┐рдо рд╕реНрдЯреНрд░рд┐рдВрдЧ str) private void invokeJS(final String str) { if(ready) { doc.eval(str); } else { webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() { @Override public void changed(final ObservableValue<? extends Worker.State> observableValue, final Worker.State oldState, final Worker.State newState) { if (newState == Worker.State.SUCCEEDED) { doc.eval(str); } } }); } }
рдкрд░рд┐рдгрд╛рдо
рдореИрдВ рдирдХреНрд╢реЗ рдХреЗ рдкреНрд░рдХрд╛рд░, рдирдХреНрд╢реЗ рдХреЗ рдХреЗрдВрджреНрд░ рдХреА рд╕реНрдерд┐рддрд┐, рдХрд░реНрд╕рд░ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЛрдВ рдХреЛ рдЕрд▓рдЧ рд╕реЗ рдирд╣реАрдВ рдмрддрд╛рдКрдВрдЧрд╛ред рдпреЗ рд╕рднреА рд╡рд┐рдзрд┐рдпрд╛рдБ рдкреВрд░реНрдг рд╕реНрд░реЛрдд рдХреЛрдб рдореЗрдВ рд╣реИрдВ:
GoogleMap.java public class GoogleMap extends Parent { public GoogleMap() { initMap(); initCommunication(); getChildren().add(webView); setMarkerPosition(0,0); setMapCenter(0, 0); switchTerrain(); } private void initMap() { webView = new WebView(); webEngine = webView.getEngine(); webEngine.load(getClass().getResource("resources/map.html").toExternalForm()); ready = false; webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() { @Override public void changed(final ObservableValue<? extends Worker.State> observableValue, final Worker.State oldState, final Worker.State newState) { if (newState == Worker.State.SUCCEEDED) { ready = true; } } }); } private void initCommunication() { webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() { @Override public void changed(final ObservableValue<? extends Worker.State> observableValue, final Worker.State oldState, final Worker.State newState) { if (newState == Worker.State.SUCCEEDED) { doc = (JSObject) webEngine.executeScript("window"); doc.setMember("app", GoogleMap.this); } } }); } private void invokeJS(final String str) { if(ready) { doc.eval(str); } else { webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() { @Override public void changed(final ObservableValue<? extends Worker.State> observableValue, final Worker.State oldState, final Worker.State newState) { if (newState == Worker.State.SUCCEEDED) { doc.eval(str); } } }); } } public void setOnMapLatLngChanged(EventHandler<MapEvent> eventHandler) { onMapLatLngChanged = eventHandler; } public void handle(double lat, double lng) { if(onMapLatLngChanged != null) { MapEvent event = new MapEvent(this, lat, lng); onMapLatLngChanged.handle(event); } } public void setMarkerPosition(double lat, double lng) { String sLat = Double.toString(lat); String sLng = Double.toString(lng); invokeJS("setMarkerPosition(" + sLat + ", " + sLng + ")"); } public void setMapCenter(double lat, double lng) { String sLat = Double.toString(lat); String sLng = Double.toString(lng); invokeJS("setMapCenter(" + sLat + ", " + sLng + ")"); } public void switchSatellite() { invokeJS("switchSatellite()"); } public void switchRoadmap() { invokeJS("switchRoadmap()"); } public void switchHybrid() { invokeJS("switchHybrid()"); } public void switchTerrain() { invokeJS("switchTerrain()"); } public void startJumping() { invokeJS("startJumping()"); } public void stopJumping() { invokeJS("stopJumping()"); } public void setHeight(double h) { webView.setPrefHeight(h); } public void setWidth(double w) { webView.setPrefWidth(w); } public ReadOnlyDoubleProperty widthProperty() { return webView.widthProperty(); } private JSObject doc; private EventHandler<MapEvent> onMapLatLngChanged; private WebView webView; private WebEngine webEngine; private boolean ready; }
map.html <!DOCTYPE html> <html> <head> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <style type="text/css"> html { height: 100% } body { height: 100%; margin: 0; padding: 0 } #map_canvas { height: 100% } </style> <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=***&sensor=false"> </script> <script type="text/javascript"> var map; var marker; function get_click_position(event){ var location = event.latLng; var lat = location.lat(); var lng = location.lng(); setMarkerPosition(lat, lng); app.handle(lat, lng); } function setMarkerPosition(lat, lng) { var clickLatLng = new google.maps.LatLng(lat, lng); marker.setPosition(clickLatLng); } function startJumping(){ marker.setAnimation(google.maps.Animation.BOUNCE); } function stopJumping(){ marker.setAnimation(google.maps.Animation.BOUNCE); } function setMapCenter(lat, lng) { var latlng = new google.maps.LatLng(lat, lng); map.setCenter(latlng); } function switchSatellite() { var mapOptions = { mapTypeId: google.maps.MapTypeId.SATELLITE }; map.setOptions(mapOptions); setLightMarkerIcon(); } function switchRoadmap() { var mapOptions = { mapTypeId: google.maps.MapTypeId.ROADMAP }; map.setOptions(mapOptions); setDarkMarkerIcon(); } function switchHybrid() { var mapOptions = { mapTypeId: google.maps.MapTypeId.HYBRID }; map.setOptions(mapOptions); setLightMarkerIcon(); } function switchTerrain() { var mapOptions = { mapTypeId: google.maps.MapTypeId.TERRAIN }; map.setOptions(mapOptions); setDarkMarkerIcon(); } function initialize() { var defLatLng = new google.maps.LatLng(59.95632093391832, 30.309906005859375); var mapOptions = { center: defLatLng, zoom: 3, mapTypeId: google.maps.MapTypeId.ROADMAP, disableDefaultUI: true, panControl: false }; map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions); google.maps.event.addListener(map, 'click', get_click_position); marker = new google.maps.Marker({ position: defLatLng, map: map, icon: "img/Pin.png" }); app.handle(0, 0); } function setDarkMarkerIcon() { marker.setIcon("img/Pin.png"); } function setLightMarkerIcon() { marker.setIcon("img/Pin_s.png"); } </script> </head> <body onload="initialize()"> <div id="map_canvas" style="width:100%; height:100%"></div> </body> </html>
рд╡реЛрд▓реНрдЯреЗрдпрд░ рдиреЗ рдХрд╣рд╛:
"рдореИрдВ рдЖрдкрдХреА рд░рд╛рдп рд╕реЗ рд╕рд╣рдордд рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛, рд▓реЗрдХрд┐рди рдореИрдВ рдЗрд╕реЗ рд╡реНрдпрдХреНрдд рдХрд░рдиреЗ рдХреЗ рдЖрдкрдХреЗ рдЕрдзрд┐рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдЕрдкрдирд╛ рдЬреАрд╡рди рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реВрдВред"