Search code examples
google-maps-api-3javafx-webengine

removing / adding markers leaves artifacts


when I clear all markers and then re-add them, I end up with artifacts. The image below shows the artifacts. the 5 buttons add one marker and then up to 5 more markers. they clear all the markers before adding new ones. clicking on the buttons 5,4,3,2,1 leaves the image below. zooming out and back in draws the markers correctly

enter image description here

swing app using jfxpanel:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Paths;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import netscape.javascript.JSObject;

@SuppressWarnings("serial")
public class FrmMap2 extends JFrame {
    private final JFXPanel jfxPanel = new JFXPanel();
    private WebEngine engine;
    private FrmMap2 me = null;

    protected String sBounds;

    public FrmMap2() {
        me = this;
        jbInit();
    }


    protected void jbInit() {
        createScene();

        JPanel pnl = new JPanel();
        pnl.setLayout(new BorderLayout());
        pnl.add(jfxPanel, BorderLayout.CENTER);

        JButton btn = new JButton("Clear");
        btn.addActionListener(evt -> onClear(0));

        JPanel pnl2 = new JPanel();
        pnl2.add(btn);

        for (int x=1; x<6;x++) {
            JButton btn1 = new JButton(""+x);
            final int y = x;
            btn1.addActionListener(evt -> onClear(y));
            pnl2.add(btn1);
        }

        pnl.add(pnl2, BorderLayout.NORTH);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setPreferredSize(new Dimension(1400, 1000));
        getContentPane().add(pnl);
        pack();
        setLocationRelativeTo(null);
    }

    protected void onClear(int level) {
        Platform.runLater(() -> { engine.executeScript("clearMarkers()"); });
        if (level > 0)
            onAddMarkers(level);
    }
    protected void onAddMarkers(int level) {
        Platform.runLater(() -> { engine.executeScript("addMarker(33.90748,-117.187289,'Test Location 1','white','Test Location 1',-1)"); });
        if (level > 0)  
            Platform.runLater(() -> { engine.executeScript("addMarker(33.9134997,-117.1915758,'Test Location 2','green','Test Location 2',957)"); });
        if (level > 1)  
            Platform.runLater(() -> { engine.executeScript("addMarker(33.9123479,-117.1915805,'Test Location 3','green','Test Location 3',958)"); });
        if (level > 2)  
            Platform.runLater(() -> { engine.executeScript("addMarker(33.913082,-117.1915775,'Test Location 4','green','Test Location 4',959)"); });
        if (level > 3)  
            Platform.runLater(() -> { engine.executeScript("addMarker(33.912805,-117.192108,'Test Location 5','green','Test Location 5',960)"); });
        if (level > 4)  
            Platform.runLater(() -> { engine.executeScript("addMarker(33.9177624,-117.203623,'Test Location 6','green','Test Location 6',1335)"); });
    }
    protected void createScene() {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {

                WebView view = new WebView();
                engine = view.getEngine();
                URL urlGoogleMaps = null;
                try {
                    urlGoogleMaps = Paths.get("mapview3.html").toUri().toURL();
                } catch (MalformedURLException e1) {
                    e1.printStackTrace();
                    return;
                }
                engine.load(urlGoogleMaps.toExternalForm());

                JSObject window = (JSObject) engine.executeScript("window");
                window.setMember("app", me);
                jfxPanel.setScene(new Scene(view));
            }
        });     
    }

    public void logit(String str) {
        System.out.println(str);
    }

    public static void main(String[] args) {
        FrmMap2 map = new FrmMap2();
        map.setVisible(true);
    }
}

html: Map html, body { height: 100%; margin: 0; padding: 0; }

#map {
    height: 100%;
}
</style>
</head>
<body onLoad="initMap()">
    <div id="map">
    <script src="https://maps.googleapis.com/maps/api/js?v=3&key=AIzaSyCcdMK5ngbSNxXno9ZRlOivVHvLoX6XyH0&libraries=places"></script>
    <script>
        var map;
        var markers = [];
        function initMap() {
            map = new google.maps.Map(document.getElementById('map'), {
                center : {
                    lat : 33.90748,
                    lng : -117.187289
                },
                zoom : 15
            });
        }

        // Removes the markers from the map, but keeps them in the array.
        function clearMarkers2() {
            for (var i = 0; i < markers.length; i++) {
                markers[i].setMap(null);
            }
        }

        function clearMarkers1() {
            markers.forEach(function(marker) {
                marker.setMap(null);
            });
        }

        function clearMarkers() {
            clearMarkers1();
            //clearMarkers2();
            markers = [];
            app.logit("MARKERS CLEARED");
        }
        function addMarker(lat, long, name, color, popover, id) {
            app.logit("ADDING MARKER: " + lat + "," + long + "," + name + "," + color + "," + id);
            var marker = createMarker("", name, new google.maps.LatLng(lat, long), popover, id);
            markers.push(marker);
        }
        function createMarker(iconname, placename, location, popover, mid) {

            // Create a marker for each place.
            var marker = new google.maps.Marker({
                map : map,
                title : placename,
                position : location
            });
            var infobulle = new google.maps.InfoWindow({
                content : popover
            });
            google.maps.event.addListener(marker, 'mouseover', function() {
                infobulle.open(map, marker);
            });
            google.maps.event.addListener(marker, 'mouseout', function() {
                infobulle.close();
            });
            return marker;
        }
    </script>
    </div>
</body>
</html>

Solution

  • Maybe not the best way to solve this question, but I was able to remove the artifacts by creating a pseudo redraw function and calling it after clearing all the markers and after adding all the new ones.

    function redraw() {
        map.setZoom(map.getZoom() - 1);
        map.setZoom(map.getZoom() + 1);
    }