JMapViewer: pan and zoom not set by when map has just loaded

500 Views Asked by At

I have two custom images as markers on JMapViewer. I would like the map to set proper pan and zoom so that the two markers are visible on the map display. I have a button that does it. So, what is happening is that the map is not zoomed to these markers when it is loading; but when I click on the button, it does. Is there a way to set the proper pan and zoom at loading?

public class PanelAcars extends javax.swing.JPanel implements JMapViewerEventListener  
{
    private final JMapViewerTree treeMap;

    public PanelAcars() 
    {
        super();
        initComponents(); // GUI components

        treeMap = new JMapViewerTree("Zones");

        // Listen to the map viewer for user operations so components will
        // receive events and update
        map().addJMVListener(this);

        setLayout(new BorderLayout());

        pnlAcarsMapView = new JPanel(new BorderLayout());
        JPanel panelTop = new JPanel();
        JPanel panelBottom = new JPanel();
        JPanel helpPanel = new JPanel();

        add(pnlAcarsMapView, BorderLayout.NORTH);
        add(helpPanel, BorderLayout.SOUTH);
        pnlAcarsMapView.add(panelTop, BorderLayout.NORTH);
        pnlAcarsMapView.add(panelBottom, BorderLayout.SOUTH);

        /* THIS BUTTON WORKS!!! */
        JButton button = new JButton("Zoom...");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                map().setDisplayToFitMapMarkers();
            }
        });


        final JCheckBox showZoomControls = new JCheckBox("Show zoom controls");
        showZoomControls.setSelected(map().getZoomControlsVisible());
        showZoomControls.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                map().setZoomContolsVisible(showZoomControls.isSelected());
            }
        });
        panelBottom.add(showZoomControls);
        final JCheckBox scrollWrapEnabled = new JCheckBox("Scrollwrap enabled");
        scrollWrapEnabled.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                map().setScrollWrapEnabled(scrollWrapEnabled.isSelected());
            }
        });
        panelBottom.add(scrollWrapEnabled);
        panelBottom.add(button);

        add(treeMap, BorderLayout.CENTER);

        /* Add Airports to the map */
        LayerGroup mapGroupAirports = new LayerGroup("MapAirports");
        Layer mapLayerDep = mapGroupAirports.addLayer("MapDep");
        Layer mapLayerDest = mapGroupAirports.addLayer("MapDest");
        Layer mapLayerAlt = mapGroupAirports.addLayer("MapAlt");


        /* Add Plane to the map */
        Layer mapLayerPlane = new Layer("MapPlane");

        /* Set coordinates */
        Coordinate coordinatesPlane = new Coordinate(49.814284999, 98.642065999);
        Coordinate coordinatesDep = new Coordinate(23.814284999, 45.642065999);

        JMapViewerMarkerCustomImage markerPlane;
        JMapViewerMarkerCustomImage markerDep;

        Image imageMarkerPlane;
        Image imageMarkerDep;

        try 
        {
            imageMarkerPlane = ImageIO.read(this.getClass().getResource("/images/image1.png"));
            markerPlane = new JMapViewerMarkerCustomImage(coordinatesPlane,imageMarkerPlane);
            map().addMapMarker(markerPlane);

            imageMarkerDep = ImageIO.read(this.getClass().getResource("/images/image2.png"));
            markerDep = new JMapViewerMarkerCustomImage(coordinatesDep,imageMarkerDep);
            map().addMapMarker(markerDep);

            // AND THIS IS NOT WORKING AT LOADING!!!
            map().setDisplayToFitMapElements(true, true, true);

        } catch (IOException ex) {
            ex.printStackTrace();
        }


        map().addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getButton() == MouseEvent.BUTTON1) {
                    map().getAttribution().handleAttribution(e.getPoint(), true);
                }
            }
        });

        map().addMouseMotionListener(new MouseAdapter() {
            @Override
            public void mouseMoved(MouseEvent e) {
                Point p = e.getPoint();
                boolean cursorHand = map().getAttribution().handleAttributionCursor(p);
                if (cursorHand) {
                    map().setCursor(new Cursor(Cursor.HAND_CURSOR));
                } else {
                    map().setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
                }
                //if (showToolTip.isSelected()) map().setToolTipText(map().getPosition(p).toString());
            }
        });

    }

Thanks a lot!

1

There are 1 best solutions below

6
trashgod On BEST ANSWER

Invoke setDisplayToFitMapMarkers() in your map's implementation of tileLoadingFinished(). Using the boolean variable loaded, which is false by default, the implementation below invokes the method after the first tile loads; the parent implementation will repaint() any subsequent tiles.

private boolean loaded;

private class MyViewer extends JMapViewer {

    @Override
    public void tileLoadingFinished(Tile tile, boolean success) {
        super.tileLoadingFinished(tile, success);
        if (!loaded & success) {
            loaded = true;
            setDisplayToFitMapMarkers();
        }
    }
    …
}

To get a similar result using JMapViewerTree, you'll need to alter the map that is instantiated in the JMapViewerTree constructor. The following changes work with Demo.java:

…
private boolean loaded;
…
public JMapViewerTree(String name, boolean treeVisible) {
    …
    map = new JMapViewer() {
        @Override
        public void tileLoadingFinished(Tile tile, boolean success) {
            super.tileLoadingFinished(tile, success);
            if (!loaded & success) {
                loaded = true;
                setDisplayToFitMapMarkers();
            }
        }
    };
    …
}

As an aside, instead of MouseAdapter, consider extending or replacing the DefaultMapController, as suggested here.