You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JavaFX WebView中从Java传JS对象给JS函数显示谷歌地图标记

我之前做过JavaFX WebView集成Google Maps的项目,刚好碰到过类似的Java传JS对象的问题,给你整理一套完整的解决方案,一步步来:

一、先完善前端HTML/JS代码

你提供的JS代码没写完,先把地图初始化逻辑补全,确保setMarker函数能正确接收坐标对象:

<!DOCTYPE html>
<html>
<head>
    <style>
        #map { height: 900px; width: 100%; }
    </style>
    <!-- 替换成你自己的Google Maps API密钥 -->
    <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_GOOGLE_API_KEY"></script>
</head>
<body>
    <div id="map"></div>
    <script>
        var map;

        // 初始化地图
        function initMap() {
            map = new google.maps.Map(document.getElementById('map'), {
                center: {lat: 39.9042, lng: 116.4074}, // 默认设为北京坐标,可按需修改
                zoom: 10
            });
        }

        // 接收JS对象参数,创建地图标记
        function setMarker(coord) {
            new google.maps.Marker({
                position: coord,
                map: map,
                title: '自定义标记' // 可按需添加标记标题
            });
        }

        // 页面加载完成后自动初始化地图
        window.addEventListener('load', initMap);
    </script>
</body>
</html>
二、JavaFX端实现:从数据库取坐标+传递JS对象给前端

核心是利用JavaFX的WebEngine和netscape.javascript.JSObject来创建JS可识别的对象,避免直接传Java对象导致的兼容问题。

1. 完整Java示例代码

import javafx.application.Application;
import javafx.concurrent.Worker;
import javafx.scene.Scene;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import netscape.javascript.JSObject;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class MapMarkerApp extends Application {
    @Override
    public void start(Stage primaryStage) {
        WebView webView = new WebView();
        WebEngine webEngine = webView.getEngine();

        // 加载本地HTML文件(替换成你的文件路径,也可以加载远程URL)
        webEngine.load(getClass().getResource("/map.html").toExternalForm());

        // 等待页面完全加载后再执行数据库查询和JS调用
        webEngine.getLoadWorker().stateProperty().addListener((obs, oldState, newState) -> {
            if (newState == Worker.State.SUCCEEDED) {
                // 从数据库读取坐标数据(替换成你的数据库连接信息和查询逻辑)
                try (Connection conn = DriverManager.getConnection(
                        "jdbc:mysql://localhost:3306/your_database",
                        "your_username",
                        "your_password"
                );
                     Statement stmt = conn.createStatement();
                     ResultSet rs = stmt.executeQuery("SELECT latitude, longitude FROM marker_points")) {

                    // 获取JS全局对象(window)
                    JSObject jsWindow = (JSObject) webEngine.executeScript("window");

                    while (rs.next()) {
                        double lat = rs.getDouble("latitude");
                        double lng = rs.getDouble("longitude");

                        // 创建JS格式的坐标对象:{lat: xxx, lng: xxx}
                        JSObject jsCoord = (JSObject) webEngine.executeScript("({})");
                        jsCoord.setMember("lat", lat);
                        jsCoord.setMember("lng", lng);

                        // 调用前端的setMarker函数,传递JS对象参数
                        jsWindow.call("setMarker", jsCoord);
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

        Scene scene = new Scene(webView, 1200, 950);
        primaryStage.setTitle("JavaFX Google Maps Marker");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

2. 备选方案:用JSON字符串传递

如果不想依赖JSObject,也可以把Java坐标对象转成JSON字符串,再在JS里解析:

// 先引入Gson或Jackson库,这里用Gson举例
import com.google.gson.Gson;

// ... 省略其他代码 ...
// 在数据库查询循环里:
double lat = rs.getDouble("latitude");
double lng = rs.getDouble("longitude");

// 把坐标转成JSON字符串
Gson gson = new Gson();
String coordJson = gson.toJson(new Coordinate(lat, lng));

// 调用JS函数,传递JSON并解析
webEngine.executeScript("setMarker(JSON.parse('" + coordJson + "'))");

// 对应的Coordinate类
class Coordinate {
    public double lat;
    public double lng;
    public Coordinate(double lat, double lng) {
        this.lat = lat;
        this.lng = lng;
    }
}
三、关键注意事项
  • 必须等页面加载完成(Worker.State.SUCCEEDED)再调用JS函数,否则map对象还未初始化会报错。
  • 数据库操作建议放在JavaFX的后台Task中执行,避免阻塞UI线程(示例为了简洁直接放在回调里,实际项目要优化)。
  • JavaFX 11+版本需要在模块路径中包含javafx.web模块,运行时要配置正确的模块依赖。

内容的提问来源于stack exchange,提问作者Egor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:32:49