Search code examples
javahtmlgoogle-mapsjavafx

JavaFX not embedding google maps html


I'm trying to embed an HTML file with google maps in a JavaFX application using WebView. I tested my code with simpler HTML files (just paragraph text and divs) and it embedded correctly but for some reason google maps will not embed. Instead it displays a white rectangle with a scroll bar.

Here is my HTML for google maps:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> GUI Embedded Map Test </title>
  <style>
    #map{
        height:600px;
        width:100%;
    }
  </style>
</head>
<body>
  <div id="map"></div>
  <script>
    function initMap() {
      window.map = new google.maps.Map(document.getElementById("map"), {
        zoom: 15,
        center:{lat:32.99069195330653, lng:-106.97436738069189},
        mapTypeId: "terrain",
      });
    }

    window.initMap = initMap;
  </script>
  <script async defer
      src="https://maps.googleapis.com/maps/api/js?key=RANDOMKEY&callback=initMap" /c/
    ></script>
</body>
</html>

(for reference, here's what it looks like when opened in a browser)

Here is my Java code for embedding it:

WebView webView = new WebView();
WebEngine webEngine = webView.getEngine();
String map_html = "";
    try {
            File myObj = new File(System.getProperty("user.dir")+"/src/main/resources/embeddedMap.html");
            Scanner myReader = new Scanner(myObj);
            while (myReader.hasNextLine()) {
            map_html += myReader.nextLine();
        map_html += "\n";
            }
            myReader.close();
    } catch (FileNotFoundException e) {
            System.out.println("An error occurred.");
        e.printStackTrace();
    }
webEngine.loadContent(map_html);
mapPane.getChildren().add(webView);

Instead of the above HTML, I've tried using iframes tags copied from the 'share' feature on google maps. I've also tried different API keys.

Any help would be greatly appreciated!


Solution

  • What you are trying to do won’t work with JavaFX 18.0.1 -> 20, see the FAQ for more detail.

    Workaround

    Try the latest version of JavaFX available and see if it will work. If not, try a version of JavaFX <=18 (some users have reported that such versions function OK with Google maps).

    Ensure that whichever version you choose, the version of all JavaFX components is exactly the same, because mixing JavaFX component versions is not supported.

    Official support for Google Maps display in JavaFX WebView

    Google doesn’t officially support JavaFX WebView in Google Maps.

    Also, there is no explicit guarantee of support the other way round from the JavaFX release notes for Google Maps in WebView.

    That doesn't mean that some versions of WebView won't work with Google maps (older versions of JavaFX have been verified to work with Google maps), only that Google don't guarantee that JavaFX WebView will be supported.

    FAQ (responses to comments by José Pereda)

    And what about GMapsFX?

    The last time I tried GMapsFX, it did not work either (that was probably with JavaFX 19 or 20). Internally GMapsFX relies on WebView for rendering Google Maps.

    The lead developer on that project comments in an issue:

    No maps are rendered when using JavaFX 18.0.1 with its upgraded WebKit version.


    Interesting, it works for me for 18 and lower, but indeed fails since 18.0.1. I wonder what change caused this, and if it is a WebKit issue, it is not that Google doesn't support WebView, but the other way around?

    This is a list of clients that Google support for their JavaScript maps client API. It does not include JavaFX, if it did they would be obligated to make it work with supported versions of JavaFX, but they don’t.


    Honestly I don't think Google considers the JavaFX WebView a "true" web browser that needs to be supported. As you know, it is an embedded browser, based on the Apple Safari Port and the WebKit GTK releases, with some modifications to make it work with Java/JavaFX. It is possible that one of those modifications broke the support for Google Maps, because it stopped working only after WebKit was updated from 612.1 to 613.1 (that is between JavaFX 18 and 18.0.1).

    When I originally wrote this answer I was unaware of the issue tracker report which mentions breakage of Google Maps between the JavaFX 18 and 18.0.1 release. I had instead assumed that Google had released a newer version of Google Maps that was incompatible with JavaFX. Perhaps this is not the case.

    I do see that Google currently explicitly support (at least for the moment), embedded browsers on other platforms like the deprecated iOS UIWebView that are not "true" browsers, so it would probably be possible for them to explicitly support the JavaFX WebView if they wanted to (my opinion). It would probably be harder for the JavaFX team to explicitly support Google Maps because it can't be known if Google will make some change to their Maps API implementation that makes it incompatible with WebView.


    Example of Google Map Display in JavaFX

    This example worked as of April 2024, using JavaFX 18 (exact version, not 18.0.1 or another version), JDK 21, OS X (x64) Sonoma 14.4.1.

    mecca

    pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>org.example</groupId>
        <artifactId>maps</artifactId>
        <version>1.0-SNAPSHOT</version>
        <name>maps</name>
    
        <dependencies>
            <dependency>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-controls</artifactId>
                <version>18</version>
            </dependency>
            <dependency>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-web</artifactId>
                <version>18</version>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.11.0</version>
                    <configuration>
                        <source>21</source>
                        <target>21</target>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>
    

    src/main/java/module-info.java

    module org.example.maps {
        requires javafx.controls;
        requires javafx.web;
    
        exports org.example.maps;
    }
    

    src/main/java/org/example/maps/MapApplication.java

    package org.example.maps;
    
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.web.WebView;
    import javafx.stage.Stage;
    
    public class MapApplication extends Application {
        @Override
        public void start(Stage stage) {
            WebView webView = new WebView();
            webView.getEngine().load("https://maps.google.com");
    
            stage.setScene(new Scene(webView));
            stage.show();
        }
    
        public static void main(String[] args) {
            launch();
        }
    }