Changeset 10458 in josm


Ignore:
Timestamp:
2016-06-22T22:18:24+02:00 (5 years ago)
Author:
Don-vip
Message:

fix #13029 - Replace hookUpMapView by attachToMapView (patch by michael2402, modified) - gsoc-core

Location:
trunk/src/org/openstreetmap/josm/gui
Files:
1 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/MapView.java

    r10440 r10458  
    2626import java.util.Collection;
    2727import java.util.Collections;
     28import java.util.HashMap;
    2829import java.util.LinkedHashSet;
    2930import java.util.List;
     
    5152import org.openstreetmap.josm.data.osm.visitor.paint.Rendering;
    5253import org.openstreetmap.josm.data.osm.visitor.paint.relations.MultipolygonCache;
     54import org.openstreetmap.josm.gui.MapViewState.MapViewRectangle;
    5355import org.openstreetmap.josm.gui.layer.AbstractMapViewPaintable;
    5456import org.openstreetmap.josm.gui.layer.GpxLayer;
     
    6264import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeEvent;
    6365import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeListener;
     66import org.openstreetmap.josm.gui.layer.MapViewGraphics;
    6467import org.openstreetmap.josm.gui.layer.MapViewPaintable;
     68import org.openstreetmap.josm.gui.layer.MapViewPaintable.LayerPainter;
     69import org.openstreetmap.josm.gui.layer.MapViewPaintable.MapViewEvent;
    6570import org.openstreetmap.josm.gui.layer.MapViewPaintable.PaintableInvalidationEvent;
    6671import org.openstreetmap.josm.gui.layer.MapViewPaintable.PaintableInvalidationListener;
    67 import org.openstreetmap.josm.gui.layer.NativeScaleLayer;
    6872import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    6973import org.openstreetmap.josm.gui.layer.geoimage.GeoImageLayer;
    70 import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
    7174import org.openstreetmap.josm.gui.layer.markerlayer.PlayHeadMarker;
    72 import org.openstreetmap.josm.gui.util.GuiHelper;
    7375import org.openstreetmap.josm.tools.AudioPlayer;
    7476import org.openstreetmap.josm.tools.Shortcut;
     
    493495
    494496    /**
     497     * This is a map of all Layers that have been added to this view.
     498     */
     499    private final HashMap<Layer, LayerPainter> registeredLayers = new HashMap<>();
     500
     501    /**
    495502     * Constructs a new {@code MapView}.
    496503     * @param layerManager The layers to display.
     
    594601    @Override
    595602    public void layerAdded(LayerAddEvent e) {
    596         Layer layer = e.getAddedLayer();
    597         if (layer instanceof MarkerLayer && playHeadMarker == null) {
    598             playHeadMarker = PlayHeadMarker.create();
    599         }
    600         if (layer instanceof NativeScaleLayer) {
    601             setNativeScaleLayer((NativeScaleLayer) layer);
    602          }
    603 
    604         ProjectionBounds viewProjectionBounds = layer.getViewProjectionBounds();
    605         if (viewProjectionBounds != null) {
    606             scheduleZoomTo(new ViewportData(viewProjectionBounds));
    607         }
    608 
    609         layer.addPropertyChangeListener(this);
    610         Main.addProjectionChangeListener(layer);
    611         invalidatedListener.addTo(layer);
    612         AudioPlayer.reset();
    613 
    614         repaint();
     603        try {
     604            Layer layer = e.getAddedLayer();
     605            registeredLayers.put(layer, layer.attachToMapView(new MapViewEvent(this, false)));
     606
     607            ProjectionBounds viewProjectionBounds = layer.getViewProjectionBounds();
     608            if (viewProjectionBounds != null) {
     609                scheduleZoomTo(new ViewportData(viewProjectionBounds));
     610            }
     611
     612            layer.addPropertyChangeListener(this);
     613            Main.addProjectionChangeListener(layer);
     614            invalidatedListener.addTo(layer);
     615            AudioPlayer.reset();
     616
     617            repaint();
     618        } catch (RuntimeException t) {
     619            throw BugReport.intercept(t).put("layer", e.getAddedLayer());
     620        }
    615621    }
    616622
     
    690696        Layer layer = e.getRemovedLayer();
    691697
     698        LayerPainter painter = registeredLayers.remove(layer);
     699        if (painter == null) {
     700            throw new IllegalArgumentException("The painter for layer " + layer + " was not registered.");
     701        }
     702        painter.detachFromMapView(new MapViewEvent(this, false));
    692703        Main.removeProjectionChangeListener(layer);
    693704        layer.removePropertyChangeListener(this);
     
    770781    private void paintLayer(Layer layer, Graphics2D g, Bounds box) {
    771782        try {
     783            LayerPainter painter = registeredLayers.get(layer);
     784            if (painter == null) {
     785                throw new IllegalArgumentException("Cannot paint layer, it is not registered.");
     786            }
     787            MapViewRectangle clipBounds = getState().getViewArea(g.getClipBounds());
     788            MapViewGraphics paintGraphics = new MapViewGraphics(this, g, clipBounds);
     789
    772790            if (layer.getOpacity() < 1) {
    773791                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) layer.getOpacity()));
    774792            }
    775             layer.paint(g, this, box);
     793            painter.paint(paintGraphics);
    776794            g.setPaintMode();
    777795        } catch (RuntimeException t) {
     796            //TODO: only display.
    778797            throw BugReport.intercept(t).put("layer", layer).put("bounds", box);
    779798        }
     
    10751094    @Override
    10761095    public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) {
    1077         /* This only makes the buttons look disabled. Disabling the actions as well requires
    1078          * the user to re-select the tool after i.e. moving a layer. While testing I found
    1079          * that I switch layers and actions at the same time and it was annoying to mind the
    1080          * order. This way it works as visual clue for new users */
    1081         for (final AbstractButton b: Main.map.allMapModeButtons) {
    1082             MapMode mode = (MapMode) b.getAction();
    1083             final boolean activeLayerSupported = mode.layerIsSupported(layerManager.getActiveLayer());
    1084             if (activeLayerSupported) {
    1085                 Main.registerActionShortcut(mode, mode.getShortcut()); //fix #6876
    1086             } else {
    1087                 Main.unregisterShortcut(mode.getShortcut());
    1088             }
    1089             GuiHelper.runInEDTAndWait(new Runnable() {
    1090                 @Override public void run() {
    1091                     b.setEnabled(activeLayerSupported);
     1096        if (Main.map != null) {
     1097            /* This only makes the buttons look disabled. Disabling the actions as well requires
     1098             * the user to re-select the tool after i.e. moving a layer. While testing I found
     1099             * that I switch layers and actions at the same time and it was annoying to mind the
     1100             * order. This way it works as visual clue for new users */
     1101            // FIXME: This does not belong here.
     1102            for (final AbstractButton b: Main.map.allMapModeButtons) {
     1103                MapMode mode = (MapMode) b.getAction();
     1104                final boolean activeLayerSupported = mode.layerIsSupported(layerManager.getActiveLayer());
     1105                if (activeLayerSupported) {
     1106                    Main.registerActionShortcut(mode, mode.getShortcut()); //fix #6876
     1107                } else {
     1108                    Main.unregisterShortcut(mode.getShortcut());
    10921109                }
    1093             });
     1110                b.setEnabled(activeLayerSupported);
     1111            }
    10941112        }
    10951113        AudioPlayer.reset();
  • trunk/src/org/openstreetmap/josm/gui/MapViewState.java

    r10399 r10458  
    44import java.awt.Container;
    55import java.awt.Point;
     6import java.awt.Rectangle;
    67import java.awt.geom.AffineTransform;
    78import java.awt.geom.Point2D;
     
    135136
    136137    /**
     138     * Gets a rectangle of the view as map view area.
     139     * @param rectangle The rectangle to get.
     140     * @return The view area.
     141     * @since 10458
     142     */
     143    public MapViewRectangle getViewArea(Rectangle rectangle) {
     144        return getForView(rectangle.getMinX(), rectangle.getMinY()).rectTo(getForView(rectangle.getMaxX(), rectangle.getMaxY()));
     145    }
     146
     147    /**
    137148     * Gets the center of the view.
    138149     * @return The center position.
     
    194205    public MapViewState movedTo(MapViewPoint mapViewPoint, EastNorth newEastNorthThere) {
    195206        EastNorth delta = newEastNorthThere.subtract(mapViewPoint.getEastNorth());
    196         if (delta.distanceSq(0, 0) < .000001) {
     207        if (delta.distanceSq(0, 0) < .1e-20) {
    197208            return this;
    198209        } else {
     
    397408         * Gets a rough estimate of the bounds by assuming lat/lon are parallel to x/y.
    398409         * @return The bounds computed by converting the corners of this rectangle.
     410         * @see #getLatLonBoundsBox()
    399411         */
    400412        public Bounds getCornerBounds() {
     
    403415            return b;
    404416        }
     417
     418        /**
     419         * Gets the real bounds that enclose this rectangle.
     420         * This is computed respecting that the borders of this rectangle may not be a straignt line in latlon coordinates.
     421         * @return The bounds.
     422         * @since 10458
     423         */
     424        public Bounds getLatLonBoundsBox() {
     425            return projection.getLatLonBoundsBox(getProjectionBounds());
     426        }
    405427    }
    406428
  • trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java

    r10446 r10458  
    5252import org.openstreetmap.josm.data.projection.Projection;
    5353import org.openstreetmap.josm.data.projection.Projections;
    54 import org.openstreetmap.josm.gui.MapViewState.MapViewPoint;
    5554import org.openstreetmap.josm.gui.help.Helpful;
    5655import org.openstreetmap.josm.gui.layer.NativeScaleLayer;
     
    454453
    455454    public ProjectionBounds getProjectionBounds(Rectangle r) {
    456         MapViewState state = getState();
    457         MapViewPoint p1 = state.getForView(r.getMinX(), r.getMinY());
    458         MapViewPoint p2 = state.getForView(r.getMaxX(), r.getMaxY());
    459         return p1.rectTo(p2).getProjectionBounds();
     455        return getState().getViewArea(r).getProjectionBounds();
    460456    }
    461457
     
    15111507     */
    15121508    public int getViewID() {
    1513         String x = getCenter().east() + '_' + getCenter().north() + '_' + getScale() + '_' +
    1514                 getWidth() + '_' + getHeight() + '_' + getProjection().toString();
     1509        EastNorth center = getCenter();
     1510        String x = new StringBuilder().append(center.east())
     1511                          .append('_').append(center.north())
     1512                          .append('_').append(getScale())
     1513                          .append('_').append(getWidth())
     1514                          .append('_').append(getHeight())
     1515                          .append('_').append(getProjection()).toString();
    15151516        CRC32 id = new CRC32();
    15161517        id.update(x.getBytes(StandardCharsets.UTF_8));
  • trunk/src/org/openstreetmap/josm/gui/layer/AbstractMapViewPaintable.java

    r10031 r10458  
    55
    66/**
    7  * This class implements the invalidation listener mechanism suggested by {@link MapViewPaintable}.
     7 * This class implements the invalidation listener mechanism suggested by {@link MapViewPaintable} and a default #atta
    88 *
    99 * @author Michael Zangl
     
    1313
    1414    /**
     15     * This is the default implementation of the layer painter.
     16     * <p>
     17     * You should not use it. Write your own implementation and put your paint code into that class.
     18     * <p>
     19     * It propagates all calls to the
     20     * {@link MapViewPaintable#paint(java.awt.Graphics2D, org.openstreetmap.josm.gui.MapView, org.openstreetmap.josm.data.Bounds)} method.
     21     * @author Michael Zangl
     22     * @since 10458
     23     */
     24    protected class CompatibilityModeLayerPainter implements LayerPainter {
     25        @Override
     26        public void paint(MapViewGraphics graphics) {
     27            AbstractMapViewPaintable.this.paint(
     28                    graphics.getDefaultGraphics(),
     29                    graphics.getMapView(),
     30                    graphics.getClipBounds().getLatLonBoundsBox());
     31        }
     32
     33        @Override
     34        public void detachFromMapView(MapViewEvent event) {
     35            // ignored in old implementation
     36        }
     37    }
     38
     39    /**
    1540     * A list of invalidation listeners to call when this layer is invalidated.
    1641     */
    1742    private final CopyOnWriteArrayList<PaintableInvalidationListener> invalidationListeners = new CopyOnWriteArrayList<>();
     43
     44    /**
     45     * This method is called whenever this layer is added to a map view.
     46     * <p>
     47     * You need to return a painter here.
     48     * The {@link MapViewPaintable.LayerPainter#detachFromMapView(MapViewEvent)} method is called when the layer is removed
     49     * from that map view. You are free to reuse painters.
     50     * <p>
     51     * You should always call the super method. See {@link #createMapViewPainter} if you want to influence painter creation.
     52     * <p>
     53     * This replaces {@link Layer#hookUpMapView} in the long run.
     54     * @param event the event.
     55     * @return A layer painter.
     56     * @since 10458
     57     */
     58    public LayerPainter attachToMapView(MapViewEvent event) {
     59        return createMapViewPainter(event);
     60    }
     61
     62    /**
     63     * Creates a new LayerPainter.
     64     * @param event The event that triggered the creation.
     65     * @return The painter.
     66     * @since 10458
     67     */
     68    protected LayerPainter createMapViewPainter(MapViewEvent event) {
     69        return new CompatibilityModeLayerPainter();
     70    }
    1871
    1972    /**
  • trunk/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java

    r10423 r10458  
    8282import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
    8383import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
    84 import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent;
    85 import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener;
    86 import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent;
    87 import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
    8884import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    8985import org.openstreetmap.josm.gui.util.GuiHelper;
     
    159155    protected TileLoader tileLoader;
    160156
     157    private final MouseAdapter adapter = new MouseAdapter() {
     158        @Override
     159        public void mouseClicked(MouseEvent e) {
     160            if (!isVisible()) return;
     161            if (e.getButton() == MouseEvent.BUTTON3) {
     162                clickedTileHolder.setTile(getTileForPixelpos(e.getX(), e.getY()));
     163                new TileSourceLayerPopup().show(e.getComponent(), e.getX(), e.getY());
     164            } else if (e.getButton() == MouseEvent.BUTTON1) {
     165                attribution.handleAttribution(e.getPoint(), true);
     166            }
     167        }
     168    };
    161169    /**
    162170     * Creates Tile Source based Imagery Layer based on Imagery Info
     
    607615        // this needs to be here and not in constructor to allow empty TileSource class construction
    608616        // using SessionWriter
    609         this.tileSource = getTileSource(info);
    610         if (this.tileSource == null) {
    611             throw new IllegalArgumentException(tr("Failed to create tile source"));
    612         }
     617        initializeIfRequired();
    613618
    614619        super.hookUpMapView();
    615         projectionChanged(null, Main.getProjection()); // check if projection is supported
    616         initTileSource(this.tileSource);
    617 
    618         final MouseAdapter adapter = new MouseAdapter() {
    619             @Override
    620             public void mouseClicked(MouseEvent e) {
    621                 if (!isVisible()) return;
    622                 if (e.getButton() == MouseEvent.BUTTON3) {
    623                     clickedTileHolder.setTile(getTileForPixelpos(e.getX(), e.getY()));
    624                     new TileSourceLayerPopup().show(e.getComponent(), e.getX(), e.getY());
    625                 } else if (e.getButton() == MouseEvent.BUTTON1) {
    626                     attribution.handleAttribution(e.getPoint(), true);
    627                 }
    628             }
    629         };
    630         Main.getLayerManager().addLayerChangeListener(new LayerChangeListener() {
    631 
    632             @Override
    633             public void layerRemoving(LayerRemoveEvent e) {
    634                 if (e.getRemovedLayer() == AbstractTileSourceLayer.this) {
    635                     Main.map.mapView.removeMouseListener(adapter);
    636                     e.getSource().removeLayerChangeListener(this);
    637                     MapView.removeZoomChangeListener(AbstractTileSourceLayer.this);
    638                 }
    639             }
    640 
    641             @Override
    642             public void layerOrderChanged(LayerOrderChangeEvent e) {
    643                 // ignored
    644             }
    645 
    646             @Override
    647             public void layerAdded(LayerAddEvent e) {
    648                 if (e.getAddedLayer() == AbstractTileSourceLayer.this) {
    649                     Main.map.mapView.addMouseListener(adapter);
    650                     MapView.addZoomChangeListener(AbstractTileSourceLayer.this);
    651                 }
    652             }
    653         }, true);
     620    }
     621
     622    @Override
     623    public LayerPainter attachToMapView(MapViewEvent event) {
     624        initializeIfRequired();
     625
     626        event.getMapView().addMouseListener(adapter);
     627        MapView.addZoomChangeListener(AbstractTileSourceLayer.this);
     628
     629        if (this instanceof NativeScaleLayer) {
     630            event.getMapView().setNativeScaleLayer((NativeScaleLayer) this);
     631        }
     632
    654633        // FIXME: why do we need this? Without this, if you add a WMS layer and do not move the mouse, sometimes, tiles do not
    655634        // start loading.
     635        // FIXME: Check if this is still required.
    656636        Main.map.repaint(500);
     637
     638        return super.attachToMapView(event);
     639    }
     640
     641    private void initializeIfRequired() {
     642        if (tileSource == null) {
     643            tileSource = getTileSource(info);
     644            if (tileSource == null) {
     645                throw new IllegalArgumentException(tr("Failed to create tile source"));
     646            }
     647            checkLayerMemoryDoesNotExceedMaximum();
     648            // check if projection is supported
     649            projectionChanged(null, Main.getProjection());
     650            initTileSource(this.tileSource);
     651        }
     652    }
     653
     654    @Override
     655    protected LayerPainter createMapViewPainter(MapViewEvent event) {
     656        return new CompatibilityModeLayerPainter() {
     657            @Override
     658            public void detachFromMapView(MapViewEvent event) {
     659                event.getMapView().removeMouseListener(adapter);
     660                MapView.removeZoomChangeListener(AbstractTileSourceLayer.this);
     661                super.detachFromMapView(event);
     662            }
     663        };
    657664    }
    658665
  • trunk/src/org/openstreetmap/josm/gui/layer/Layer.java

    r10378 r10458  
    1717import javax.swing.JOptionPane;
    1818import javax.swing.JSeparator;
     19import javax.swing.SwingUtilities;
    1920
    2021import org.openstreetmap.josm.Main;
     
    169170     */
    170171    public void hookUpMapView() {
     172        checkLayerMemoryDoesNotExceedMaximum();
     173    }
     174
     175    /**
     176     * Checks that the memory required for the layers is no greather than the max memory.
     177     */
     178    protected static void checkLayerMemoryDoesNotExceedMaximum() {
    171179        // calculate total memory needed for all layers
    172180        long memoryBytesRequired = 50L * 1024L * 1024L; // assumed minimum JOSM memory footprint
    173         if (Main.map != null && Main.map.mapView != null) {
    174             for (Layer layer: Main.getLayerManager().getLayers()) {
    175                 memoryBytesRequired += layer.estimateMemoryUsage();
    176             }
    177             if (memoryBytesRequired > Runtime.getRuntime().maxMemory()) {
    178                 throw new IllegalArgumentException(
    179                         tr("To add another layer you need to allocate at least {0,number,#}MB memory to JOSM using -Xmx{0,number,#}M "
    180                         + "option (see http://forum.openstreetmap.org/viewtopic.php?id=25677).\n"
    181                         + "Currently you have {1,number,#}MB memory allocated for JOSM",
    182                         memoryBytesRequired / 1024 / 1024, Runtime.getRuntime().maxMemory() / 1024 / 1024));
    183             }
     181        for (Layer layer: Main.getLayerManager().getLayers()) {
     182            memoryBytesRequired += layer.estimateMemoryUsage();
     183        }
     184        if (memoryBytesRequired > Runtime.getRuntime().maxMemory()) {
     185            throw new IllegalArgumentException(
     186                    tr("To add another layer you need to allocate at least {0,number,#}MB memory to JOSM using -Xmx{0,number,#}M "
     187                            + "option (see http://forum.openstreetmap.org/viewtopic.php?id=25677).\n"
     188                            + "Currently you have {1,number,#}MB memory allocated for JOSM",
     189                            memoryBytesRequired / 1024 / 1024, Runtime.getRuntime().maxMemory() / 1024 / 1024));
    184190        }
    185191    }
     
    526532    public void projectionChanged(Projection oldValue, Projection newValue) {
    527533        if (!isProjectionSupported(newValue)) {
    528             String message = "<html><body><p>" +
     534            final String message = "<html><body><p>" +
    529535                    tr("The layer {0} does not support the new projection {1}.", getName(), newValue.toCode()) + "</p>" +
    530536                    "<p style='width: 450px;'>" + tr("Supported projections are: {0}", nameSupportedProjections()) + "</p>" +
    531537                    tr("Change the projection again or remove the layer.");
    532538
    533             JOptionPane.showMessageDialog(Main.parent,
    534                     message,
    535                     tr("Warning"),
    536                     JOptionPane.WARNING_MESSAGE);
     539            // run later to not block loading the UI.
     540            SwingUtilities.invokeLater(new Runnable() {
     541                @Override
     542                public void run() {
     543                    JOptionPane.showMessageDialog(Main.parent,
     544                            message,
     545                            tr("Warning"),
     546                            JOptionPane.WARNING_MESSAGE);
     547                }
     548            });
    537549        }
    538550    }
  • trunk/src/org/openstreetmap/josm/gui/layer/LayerManager.java

    r10432 r10458  
    99import org.openstreetmap.josm.gui.util.GuiHelper;
    1010import org.openstreetmap.josm.tools.Utils;
     11import org.openstreetmap.josm.tools.bugreport.BugReport;
    1112
    1213/**
     
    8283            return addedLayer;
    8384        }
     85
     86        @Override
     87        public String toString() {
     88            return "LayerAddEvent [addedLayer=" + addedLayer + ']';
     89        }
    8490    }
    8591
     
    114120            return lastLayer;
    115121        }
     122
     123        @Override
     124        public String toString() {
     125            return "LayerRemoveEvent [removedLayer=" + removedLayer + ", lastLayer=" + lastLayer + ']';
     126        }
    116127    }
    117128
     
    127138        }
    128139
     140        @Override
     141        public String toString() {
     142            return "LayerOrderChangeEvent []";
     143        }
    129144    }
    130145
     
    339354        LayerAddEvent e = new LayerAddEvent(this, layer);
    340355        for (LayerChangeListener l : layerChangeListeners) {
    341             l.layerAdded(e);
     356            try {
     357                l.layerAdded(e);
     358            } catch (RuntimeException t) {
     359                throw BugReport.intercept(t).put("listener", l).put("event", e);
     360            }
    342361        }
    343362    }
     
    347366        LayerRemoveEvent e = new LayerRemoveEvent(this, layer);
    348367        for (LayerChangeListener l : layerChangeListeners) {
    349             l.layerRemoving(e);
     368            try {
     369                l.layerRemoving(e);
     370            } catch (RuntimeException t) {
     371                throw BugReport.intercept(t).put("listener", l).put("event", e);
     372            }
    350373        }
    351374    }
     
    355378        LayerOrderChangeEvent e = new LayerOrderChangeEvent(this);
    356379        for (LayerChangeListener l : layerChangeListeners) {
    357             l.layerOrderChanged(e);
     380            try {
     381                l.layerOrderChanged(e);
     382            } catch (RuntimeException t) {
     383                throw BugReport.intercept(t).put("listener", l).put("event", e);
     384            }
    358385        }
    359386    }
  • trunk/src/org/openstreetmap/josm/gui/layer/MapViewPaintable.java

    r10300 r10458  
    6161
    6262    /**
     63     * Gets a new LayerPainter that paints this {@link MapViewPaintable} to the given map view.
     64     *
     65     * @author Michael Zangl
     66     * @since 10458
     67     */
     68    public interface LayerPainter {
     69
     70        /**
     71         * Paints the given layer.
     72         * <p>
     73         * This can be called in any thread at any time. You will not receive parallel calls for the same map view but you can receive parallel
     74         * calls if you use the same {@link LayerPainter} for different map views.
     75         * @param graphics The graphics object of the map view you should use.
     76         *                 It provides you with a content pane, the bounds and the view state.
     77         */
     78        void paint(MapViewGraphics graphics);
     79
     80        /**
     81         * Called when the layer is removed from the map view and this painter is not used any more.
     82         * <p>
     83         * This method is called once on the painter returned by {@link Layer#attachToMapView(MapViewEvent)}
     84         * @param event The event.
     85         */
     86        void detachFromMapView(MapViewEvent event);
     87    }
     88
     89    /**
     90     * A event that is fired whenever the map view is attached or detached from any layer.
     91     * @author Michael Zangl
     92     * @see Layer#attachToMapView(MapViewEvent)
     93     * @since 10458
     94     */
     95    class MapViewEvent {
     96        private final MapView mapView;
     97        private final boolean temporaryLayer;
     98
     99        /**
     100         * Create a new {@link MapViewEvent}
     101         * @param mapView The map view
     102         * @param temporaryLayer <code>true</code> if this layer is in the temporary layer list of the view.
     103         */
     104        public MapViewEvent(MapView mapView, boolean temporaryLayer) {
     105            super();
     106            this.mapView = mapView;
     107            this.temporaryLayer = temporaryLayer;
     108        }
     109
     110        /**
     111         * Gets the map view.
     112         * @return The map view.
     113         */
     114        public MapView getMapView() {
     115            return mapView;
     116        }
     117
     118        /**
     119         * @return true if this {@link MapViewPaintable} is used as a temporary layer.
     120         */
     121        public boolean isTemporaryLayer() {
     122            return temporaryLayer;
     123        }
     124
     125        @Override
     126        public String toString() {
     127            return "AttachToMapViewEvent [mapView=" + mapView + ", temporaryLayer=" + temporaryLayer + "]";
     128        }
     129    }
     130
     131    /**
    63132     * Paint the dataset using the engine set.
    64133     * @param g Graphics
  • trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java

    r10378 r10458  
    139139
    140140    @Override
    141     public void hookUpMapView() {
    142         Main.map.mapView.addMouseListener(new MouseAdapter() {
     141    public LayerPainter attachToMapView(MapViewEvent event) {
     142        event.getMapView().addMouseListener(new MouseAdapter() {
    143143            @Override
    144144            public void mousePressed(MouseEvent e) {
     
    179179            }
    180180        });
     181
     182        if (event.getMapView().playHeadMarker == null) {
     183            event.getMapView().playHeadMarker = PlayHeadMarker.create();
     184        }
     185
     186        return super.attachToMapView(event);
    181187    }
    182188
Note: See TracChangeset for help on using the changeset viewer.