Changes in trunk/src [10274:10270] in josm


Ignore:
Location:
trunk/src/org/openstreetmap/josm
Files:
2 deleted
6 edited

Legend:

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

    r10274 r10270  
    8787import org.openstreetmap.josm.gui.MapFrame;
    8888import org.openstreetmap.josm.gui.MapFrameListener;
     89import org.openstreetmap.josm.gui.MapView;
    8990import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
    9091import org.openstreetmap.josm.gui.help.HelpUtil;
     
    9293import org.openstreetmap.josm.gui.layer.AbstractModifiableLayer;
    9394import org.openstreetmap.josm.gui.layer.Layer;
    94 import org.openstreetmap.josm.gui.layer.LayerManagerWithActive;
    9595import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    9696import org.openstreetmap.josm.gui.layer.OsmDataLayer.CommandQueueListener;
     
    190190    /**
    191191     * The MapFrame. Use {@link Main#setMapFrame} to set or clear it.
    192      * <p>
    193      * There should be no need to access this to access any map data. Use {@link #layerManager} instead.
    194192     */
    195193    public static MapFrame map;
    196 
    197     /**
    198      * Provides access to the layers displayed in the main view.
    199      * @since 10271
    200      */
    201     private static final LayerManagerWithActive layerManager = new LayerManagerWithActive();
    202194
    203195    /**
     
    539531    public final synchronized void removeLayer(final Layer layer) {
    540532        if (map != null) {
    541             getLayerManager().removeLayer(layer);
    542             if (isDisplayingMapView() && getLayerManager().getLayers().isEmpty()) {
     533            map.mapView.removeLayer(layer);
     534            if (isDisplayingMapView() && map.mapView.getAllLayers().isEmpty()) {
    543535                setMapFrame(null);
    544536            }
     
    616608            public void initialize() {
    617609                validator = new OsmValidator();
    618                 getLayerManager().addLayerChangeListener(validator);
     610                MapView.addLayerChangeListener(validator);
    619611            }
    620612        });
     
    738730
    739731    /**
    740      * Returns the main layer manager that is used by the map view.
    741      * @return The layer manager. The value returned will never change.
    742      * @since 10271
    743      */
    744     public static LayerManagerWithActive getLayerManager() {
    745         return layerManager;
    746     }
    747 
    748     /**
    749732     * Add a new layer to the map.
    750733     *
     
    790773        }
    791774        layer.hookUpMapView();
    792         getLayerManager().addLayer(layer);
     775        map.mapView.addLayer(layer);
    793776        if (noMap) {
    794777            Main.map.setVisible(true);
     
    830813    public OsmDataLayer getEditLayer() {
    831814        if (!isDisplayingMapView()) return null;
    832         return getLayerManager().getEditLayer();
     815        return map.mapView.getEditLayer();
    833816    }
    834817
     
    869852    public Layer getActiveLayer() {
    870853        if (!isDisplayingMapView()) return null;
    871         return getLayerManager().getActiveLayer();
     854        return map.mapView.getActiveLayer();
    872855    }
    873856
     
    10501033    public static boolean saveUnsavedModifications() {
    10511034        if (!isDisplayingMapView()) return true;
    1052         return saveUnsavedModifications(getLayerManager().getLayersOfType(AbstractModifiableLayer.class), true);
     1035        return saveUnsavedModifications(map.mapView.getLayersOfType(AbstractModifiableLayer.class), true);
    10531036    }
    10541037
     
    11171100            // Remove all layers because somebody may rely on layerRemoved events (like AutosaveTask)
    11181101            if (Main.isDisplayingMapView()) {
    1119                 Collection<Layer> layers = new ArrayList<>(getLayerManager().getLayers());
     1102                Collection<Layer> layers = new ArrayList<>(Main.map.mapView.getAllLayers());
    11201103                for (Layer l: layers) {
    11211104                    Main.main.removeLayer(l);
  • trunk/src/org/openstreetmap/josm/data/validation/OsmValidator.java

    r10274 r10270  
    5959import org.openstreetmap.josm.data.validation.tests.WayConnectedToArea;
    6060import org.openstreetmap.josm.data.validation.tests.WronglyOrderedWays;
    61 import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent;
    62 import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener;
    63 import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent;
    64 import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
     61import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
     62import org.openstreetmap.josm.gui.layer.Layer;
    6563import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    6664import org.openstreetmap.josm.gui.layer.ValidatorLayer;
     
    341339    /* -------------------------------------------------------------------------- */
    342340    @Override
    343     public void layerAdded(LayerAddEvent e) {
    344         // do nothing
     341    public void activeLayerChange(Layer oldLayer, Layer newLayer) {
     342        // Do nothing
    345343    }
    346344
    347345    @Override
    348     public void layerOrderChanged(LayerOrderChangeEvent e) {
    349         // do nothing
     346    public void layerAdded(Layer newLayer) {
     347        // Do nothing
    350348    }
    351349
    352350    @Override
    353     public void layerRemoving(LayerRemoveEvent e) {
    354         if (e.getRemovedLayer() == errorLayer) {
     351    public void layerRemoved(Layer oldLayer) {
     352        if (oldLayer == errorLayer) {
    355353            errorLayer = null;
    356354            return;
    357355        }
    358         if (e.getSource().getLayersOfType(OsmDataLayer.class).isEmpty()) {
     356        if (Main.map.mapView.getLayersOfType(OsmDataLayer.class).isEmpty()) {
    359357            if (errorLayer != null) {
    360358                Main.main.removeLayer(errorLayer);
  • trunk/src/org/openstreetmap/josm/gui/MapFrame.java

    r10274 r10270  
    7676import org.openstreetmap.josm.gui.dialogs.properties.PropertiesDialog;
    7777import org.openstreetmap.josm.gui.layer.Layer;
    78 import org.openstreetmap.josm.gui.layer.LayerManager;
    7978import org.openstreetmap.josm.gui.util.AdvancedKeyPressDetector;
    8079import org.openstreetmap.josm.tools.Destroyable;
     
    9998    /**
    10099     * The view control displayed.
    101      * <p>
    102      * Accessing this is discouraged. Use the {@link LayerManager} to access map data.
    103100     */
    104101    public final MapView mapView;
     
    193190        setLayout(new BorderLayout());
    194191
    195         mapView = new MapView(Main.getLayerManager(), contentPane, viewportData);
     192        mapView = new MapView(contentPane, viewportData);
    196193        if (!GraphicsEnvironment.isHeadless()) {
    197194            new FileDrop(mapView);
     
    778775            }
    779776            // invalidate repaint cache
    780             mapView.preferenceChanged(null);
     777            Main.map.mapView.preferenceChanged(null);
    781778        }
    782779
  • trunk/src/org/openstreetmap/josm/gui/MapView.java

    r10274 r10270  
    2626import java.util.Collection;
    2727import java.util.Collections;
     28import java.util.EnumSet;
    2829import java.util.LinkedHashSet;
    2930import java.util.List;
     31import java.util.ListIterator;
    3032import java.util.Set;
    3133import java.util.concurrent.CopyOnWriteArrayList;
     
    5759import org.openstreetmap.josm.gui.layer.ImageryLayer;
    5860import org.openstreetmap.josm.gui.layer.Layer;
    59 import org.openstreetmap.josm.gui.layer.LayerManager;
    60 import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent;
    61 import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent;
    62 import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
    63 import org.openstreetmap.josm.gui.layer.LayerManagerWithActive;
    64 import org.openstreetmap.josm.gui.layer.LayerManagerWithActive.ActiveLayerChangeEvent;
    65 import org.openstreetmap.josm.gui.layer.LayerManagerWithActive.ActiveLayerChangeListener;
     61import org.openstreetmap.josm.gui.layer.LayerPositionStrategy;
    6662import org.openstreetmap.josm.gui.layer.MapViewPaintable;
    6763import org.openstreetmap.josm.gui.layer.MapViewPaintable.PaintableInvalidationEvent;
    6864import org.openstreetmap.josm.gui.layer.MapViewPaintable.PaintableInvalidationListener;
     65import org.openstreetmap.josm.gui.layer.NativeScaleLayer;
    6966import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    7067import org.openstreetmap.josm.gui.layer.geoimage.GeoImageLayer;
     
    9087 */
    9188public class MapView extends NavigatableComponent
    92 implements PropertyChangeListener, PreferenceChangedListener, OsmDataLayer.LayerStateChangeListener,
    93 LayerManager.LayerChangeListener, LayerManagerWithActive.ActiveLayerChangeListener {
     89implements PropertyChangeListener, PreferenceChangedListener, OsmDataLayer.LayerStateChangeListener {
     90
    9491    /**
    9592     * Interface to notify listeners of a layer change.
    96      * <p>
    97      * To be removed: end of 2016. Use {@link org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener} instead.
    9893     * @author imi
    9994     */
    100     @Deprecated
    10195    public interface LayerChangeListener {
    10296
     
    123117    /**
    124118     * An interface that needs to be implemented in order to listen for changes to the active edit layer.
    125      * <p>
    126      * To be removed: end of 2016. Use {@link ActiveLayerChangeListener} instead.
    127      */
    128     @Deprecated
     119     */
    129120    public interface EditLayerChangeListener {
    130121
     
    140131     * An invalidation listener that simply calls repaint() for now.
    141132     * @author Michael Zangl
    142      * @since 10271
    143133     */
    144134    private class LayerInvalidatedListener implements PaintableInvalidationListener {
     
    182172    }
    183173
    184     /**
    185      * This class is an adapter for the old layer change interface.
    186      * <p>
    187      * New implementations should use {@link org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener}
    188      * @author Michael Zangl
    189      * @since 10271
    190      */
    191     protected static class LayerChangeAdapter implements ActiveLayerChangeListener, LayerManager.LayerChangeListener {
    192 
    193         private final LayerChangeListener wrapped;
    194         private boolean receiveOneInitialFire;
    195 
    196         public LayerChangeAdapter(LayerChangeListener wrapped) {
    197             this.wrapped = wrapped;
    198         }
    199 
    200         public LayerChangeAdapter(LayerChangeListener wrapped, boolean initialFire) {
    201             this(wrapped);
    202             this.receiveOneInitialFire = initialFire;
    203         }
    204 
    205         @Override
    206         public void layerAdded(LayerAddEvent e) {
    207             wrapped.layerAdded(e.getAddedLayer());
    208         }
    209 
    210         @Override
    211         public void layerRemoving(LayerRemoveEvent e) {
    212             wrapped.layerRemoved(e.getRemovedLayer());
    213         }
    214 
    215         @Override
    216         public void layerOrderChanged(LayerOrderChangeEvent e) {
    217             // not in old API
    218         }
    219 
    220         @Override
    221         public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) {
    222             Layer oldActive = receiveOneInitialFire ? null : e.getPreviousActiveLayer();
    223             Layer newActive = e.getSource().getActiveLayer();
    224             if (oldActive != newActive) {
    225                 wrapped.activeLayerChange(oldActive, newActive);
    226             }
    227             receiveOneInitialFire = false;
    228         }
    229 
    230         @Override
    231         public int hashCode() {
    232             final int prime = 31;
    233             int result = 1;
    234             result = prime * result + ((wrapped == null) ? 0 : wrapped.hashCode());
    235             return result;
    236         }
    237 
    238         @Override
    239         public boolean equals(Object obj) {
    240             if (this == obj)
    241                 return true;
    242             if (obj == null)
    243                 return false;
    244             if (getClass() != obj.getClass())
    245                 return false;
    246             LayerChangeAdapter other = (LayerChangeAdapter) obj;
    247             if (wrapped == null) {
    248                 if (other.wrapped != null)
    249                     return false;
    250             } else if (!wrapped.equals(other.wrapped))
    251                 return false;
    252             return true;
    253         }
    254 
    255         @Override
    256         public String toString() {
    257             return "LayerChangeAdapter [wrapped=" + wrapped + "]";
    258         }
    259 
    260     }
    261 
    262     /**
    263      * This class is an adapter for the old layer change interface.
    264      * <p>
    265      * New implementations should use {@link org.openstreetmap.josm.gui.layer.LayerManagerWithActive.ActiveLayerChangeListener}
    266      * @author Michael Zangl
    267      * @since 10271
    268      */
    269     protected static class EditLayerChangeAdapter implements ActiveLayerChangeListener {
    270 
    271         private final EditLayerChangeListener wrapped;
    272 
    273         public EditLayerChangeAdapter(EditLayerChangeListener wrapped) {
    274             this.wrapped = wrapped;
    275         }
    276 
    277         @Override
    278         public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) {
    279             OsmDataLayer oldLayer = e.getPreviousEditLayer();
    280             OsmDataLayer newLayer = e.getSource().getEditLayer();
    281             if (oldLayer != newLayer) {
    282                 wrapped.editLayerChanged(oldLayer, newLayer);
    283             }
    284         }
    285 
    286         @Override
    287         public int hashCode() {
    288             final int prime = 31;
    289             int result = 1;
    290             result = prime * result + ((wrapped == null) ? 0 : wrapped.hashCode());
    291             return result;
    292         }
    293 
    294         @Override
    295         public boolean equals(Object obj) {
    296             if (this == obj)
    297                 return true;
    298             if (obj == null)
    299                 return false;
    300             if (getClass() != obj.getClass())
    301                 return false;
    302             EditLayerChangeAdapter other = (EditLayerChangeAdapter) obj;
    303             if (wrapped == null) {
    304                 if (other.wrapped != null)
    305                     return false;
    306             } else if (!wrapped.equals(other.wrapped))
    307                 return false;
    308             return true;
    309         }
    310 
    311         @Override
    312         public String toString() {
    313             return "EditLayerChangeAdapter [wrapped=" + wrapped + "]";
    314         }
    315 
    316     }
     174    public boolean viewportFollowing;
     175
     176    /**
     177     * the layer listeners
     178     */
     179    private static final CopyOnWriteArrayList<LayerChangeListener> layerChangeListeners = new CopyOnWriteArrayList<>();
     180    private static final CopyOnWriteArrayList<EditLayerChangeListener> editLayerChangeListeners = new CopyOnWriteArrayList<>();
    317181
    318182    /**
    319183     * Removes a layer change listener
    320      * <p>
    321      * You should register the listener on {@link Main#getLayerManager()} instead. To be removed: end of 2016.
    322      *
    323      * @param listener the listener. Ignored if null or not registered.
    324      */
    325     @Deprecated
     184     *
     185     * @param listener the listener. Ignored if null or already registered.
     186     */
    326187    public static void removeLayerChangeListener(LayerChangeListener listener) {
    327         LayerChangeAdapter adapter = new LayerChangeAdapter(listener);
    328         try {
    329             Main.getLayerManager().removeLayerChangeListener(adapter);
    330         } catch (IllegalArgumentException e) {
    331             // Ignored in old implementation
    332         }
    333         try {
    334             Main.getLayerManager().removeActiveLayerChangeListener(adapter);
    335         } catch (IllegalArgumentException e) {
    336             // Ignored in old implementation
    337         }
    338     }
    339 
    340     /**
    341      * Removes an edit layer change listener
    342      * <p>
    343      * You should register the listener on {@link Main#getLayerManager()} instead. To be removed: end of 2016.
    344      *
    345      * @param listener the listener. Ignored if null or not registered.
    346      */
    347     @Deprecated
     188        layerChangeListeners.remove(listener);
     189    }
     190
    348191    public static void removeEditLayerChangeListener(EditLayerChangeListener listener) {
    349         try {
    350             Main.getLayerManager().removeActiveLayerChangeListener(new EditLayerChangeAdapter(listener));
    351         } catch (IllegalArgumentException e) {
    352             // Ignored in old implementation
    353         }
     192        editLayerChangeListeners.remove(listener);
    354193    }
    355194
    356195    /**
    357196     * Adds a layer change listener
    358      * <p>
    359      * You should register the listener on {@link Main#getLayerManager()} instead. To be removed: end of 2016.
    360197     *
    361198     * @param listener the listener. Ignored if null or already registered.
    362199     */
    363     @Deprecated
    364200    public static void addLayerChangeListener(LayerChangeListener listener) {
    365         addLayerChangeListener(listener, false);
     201        if (listener != null) {
     202            layerChangeListeners.addIfAbsent(listener);
     203        }
    366204    }
    367205
    368206    /**
    369207     * Adds a layer change listener
    370      * <p>
    371      * You should register the listener on {@link Main#getLayerManager()} instead. To be removed: end of 2016.
    372208     *
    373209     * @param listener the listener. Ignored if null or already registered.
     
    375211     * the listener in case there is a layer present (should be)
    376212     */
    377     @Deprecated
    378213    public static void addLayerChangeListener(LayerChangeListener listener, boolean initialFire) {
    379         if (listener != null) {
    380             initialFire = initialFire && Main.isDisplayingMapView();
    381 
    382             LayerChangeAdapter adapter = new LayerChangeAdapter(listener, initialFire);
    383             Main.getLayerManager().addLayerChangeListener(adapter, false);
    384             Main.getLayerManager().addActiveLayerChangeListener(adapter, initialFire);
    385             adapter.receiveOneInitialFire = false;
     214        addLayerChangeListener(listener);
     215        if (initialFire && Main.isDisplayingMapView()) {
     216            listener.activeLayerChange(null, Main.map.mapView.getActiveLayer());
    386217        }
    387218    }
     
    389220    /**
    390221     * Adds an edit layer change listener
    391      * <p>
    392      * You should register the listener on {@link Main#getLayerManager()} instead. To be removed: end of 2016.
    393222     *
    394223     * @param listener the listener. Ignored if null or already registered.
     
    396225     * the listener in case there is an edit layer present
    397226     */
    398     @Deprecated
    399227    public static void addEditLayerChangeListener(EditLayerChangeListener listener, boolean initialFire) {
     228        addEditLayerChangeListener(listener);
     229        if (initialFire && Main.isDisplayingMapView() && Main.map.mapView.getEditLayer() != null) {
     230            listener.editLayerChanged(null, Main.map.mapView.getEditLayer());
     231        }
     232    }
     233
     234    /**
     235     * Adds an edit layer change listener
     236     *
     237     * @param listener the listener. Ignored if null or already registered.
     238     */
     239    public static void addEditLayerChangeListener(EditLayerChangeListener listener) {
    400240        if (listener != null) {
    401             Main.getLayerManager().addActiveLayerChangeListener(new EditLayerChangeAdapter(listener), initialFire && Main.isDisplayingMapView() && Main.map.mapView.getEditLayer() != null);
    402         }
    403     }
    404 
    405     /**
    406      * Adds an edit layer change listener
    407      * <p>
    408      * You should register the listener on {@link Main#getLayerManager()} instead. To be removed: end of 2016.
    409      *
    410      * @param listener the listener. Ignored if null or already registered.
    411      */
    412     @Deprecated
    413     public static void addEditLayerChangeListener(EditLayerChangeListener listener) {
    414         addEditLayerChangeListener(listener, false);
    415     }
    416 
    417     public boolean viewportFollowing = false;
    418 
    419     /**
    420      * A list of all layers currently loaded. If we support multiple map views, this list may be different for each of them.
    421      */
    422     private final LayerManagerWithActive layerManager;
     241            editLayerChangeListeners.addIfAbsent(listener);
     242        }
     243    }
     244
     245    /**
     246     * Calls the {@link LayerChangeListener#activeLayerChange(Layer, Layer)} method of all listeners.
     247     *
     248     * @param oldLayer The old layer
     249     * @param newLayer The new active layer.
     250     */
     251    protected void fireActiveLayerChanged(Layer oldLayer, Layer newLayer) {
     252        for (LayerChangeListener l : layerChangeListeners) {
     253            l.activeLayerChange(oldLayer, newLayer);
     254        }
     255    }
     256
     257    protected void fireLayerAdded(Layer newLayer) {
     258        for (MapView.LayerChangeListener l : MapView.layerChangeListeners) {
     259            l.layerAdded(newLayer);
     260        }
     261    }
     262
     263    protected void fireLayerRemoved(Layer layer) {
     264        for (MapView.LayerChangeListener l : MapView.layerChangeListeners) {
     265            l.layerRemoved(layer);
     266        }
     267    }
     268
     269    protected void fireEditLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) {
     270        for (EditLayerChangeListener l : editLayerChangeListeners) {
     271            l.editLayerChanged(oldLayer, newLayer);
     272        }
     273    }
     274
     275    /**
     276     * A list of all layers currently loaded.
     277     */
     278    private final transient List<Layer> layers = new ArrayList<>();
    423279
    424280    /**
     
    426282     */
    427283    public transient PlayHeadMarker playHeadMarker;
     284
     285    /**
     286     * The layer from the layers list that is currently active.
     287     */
     288    private transient Layer activeLayer;
     289
     290    /**
     291     * The edit layer is the current active data layer.
     292     */
     293    private transient OsmDataLayer editLayer;
    428294
    429295    /**
     
    456322    /**
    457323     * Constructs a new {@code MapView}.
    458      * @param layerManager The layers to display.
    459324     * @param contentPane The content pane used to register shortcuts in its
    460325     * {@link InputMap} and {@link ActionMap}
     
    462327     * the viewport is derived from the layer data.
    463328     */
    464     public MapView(LayerManagerWithActive layerManager, final JPanel contentPane, final ViewportData viewportData) {
    465         this.layerManager = layerManager;
     329    public MapView(final JPanel contentPane, final ViewportData viewportData) {
    466330        initialViewport = viewportData;
    467         layerManager.addLayerChangeListener(this);
    468         layerManager.addActiveLayerChangeListener(this, false);
    469331        Main.pref.addPreferenceChangeListener(this);
    470332
     
    543405
    544406    /**
    545      * Add a layer to the current MapView.
    546      * <p>
    547      * Use {@link Main#getLayerManager()}.addLayer() instead. To be removed: end of 2016.
     407     * Add a layer to the current MapView. The layer will be added at topmost
     408     * position.
    548409     * @param layer The layer to add
    549410     */
    550     @Deprecated
    551411    public void addLayer(Layer layer) {
    552         layerManager.addLayer(layer);
     412        boolean isOsmDataLayer = layer instanceof OsmDataLayer;
     413        EnumSet<LayerListenerType> listenersToFire = EnumSet.noneOf(LayerListenerType.class);
     414        Layer oldActiveLayer = activeLayer;
     415        OsmDataLayer oldEditLayer = editLayer;
     416
     417        synchronized (layers) {
     418            if (layer instanceof MarkerLayer && playHeadMarker == null) {
     419                playHeadMarker = PlayHeadMarker.create();
     420            }
     421
     422            LayerPositionStrategy positionStrategy = layer.getDefaultLayerPosition();
     423            int position = positionStrategy.getPosition(this);
     424            checkPosition(position);
     425            insertLayerAt(layer, position);
     426
     427            if (isOsmDataLayer || oldActiveLayer == null) {
     428                // autoselect the new layer
     429                listenersToFire.addAll(setActiveLayer(layer, true));
     430            }
     431
     432            if (isOsmDataLayer) {
     433                ((OsmDataLayer) layer).addLayerStateChangeListener(this);
     434            }
     435
     436            if (layer instanceof NativeScaleLayer) {
     437                Main.map.mapView.setNativeScaleLayer((NativeScaleLayer) layer);
     438            }
     439
     440            layer.addPropertyChangeListener(this);
     441            invalidatedListener.addTo(layer);
     442            Main.addProjectionChangeListener(layer);
     443            AudioPlayer.reset();
     444        }
     445        fireLayerAdded(layer);
     446        onActiveEditLayerChanged(oldActiveLayer, oldEditLayer, listenersToFire);
     447
     448        if (!listenersToFire.isEmpty()) {
     449            repaint();
     450        }
     451    }
     452
     453    /**
     454     * Check if the (new) position is valid
     455     * @param position The position index
     456     * @throws IndexOutOfBoundsException if it is not.
     457     */
     458    private void checkPosition(int position) {
     459        if (position < 0 || position > layers.size()) {
     460            throw new IndexOutOfBoundsException("Position " + position + " out of range.");
     461        }
     462    }
     463
     464    /**
     465     * Insert a layer at a given position.
     466     * @param layer The layer to add.
     467     * @param position The position on which we should add it.
     468     */
     469    private void insertLayerAt(Layer layer, int position) {
     470        if (position == layers.size()) {
     471            layers.add(layer);
     472        } else {
     473            layers.add(position, layer);
     474        }
    553475    }
    554476
    555477    @Override
    556     public void layerAdded(LayerAddEvent e) {
    557         Layer layer = e.getAddedLayer();
    558         if (layer instanceof MarkerLayer && playHeadMarker == null) {
    559             playHeadMarker = PlayHeadMarker.create();
    560         }
    561 
    562         boolean isOsmDataLayer = layer instanceof OsmDataLayer;
    563         if (isOsmDataLayer) {
    564             ((OsmDataLayer) layer).addLayerStateChangeListener(this);
    565         }
    566 
    567         layer.addPropertyChangeListener(this);
    568         Main.addProjectionChangeListener(layer);
    569         invalidatedListener.addTo(layer);
    570         AudioPlayer.reset();
    571 
    572         repaint();
    573     }
    574 
    575     /**
    576      * Use {@link Main#getLayerManager()} instead. To be removed: end of 2016.
    577      */
    578     @Override
    579     @Deprecated
    580478    protected DataSet getCurrentDataSet() {
    581         return layerManager.getEditDataSet();
     479        synchronized (layers) {
     480            if (editLayer != null)
     481                return editLayer.data;
     482            else
     483                return null;
     484        }
    582485    }
    583486
     
    588491     */
    589492    public boolean isActiveLayerDrawable() {
    590          return getEditLayer() != null;
     493        synchronized (layers) {
     494            return editLayer != null;
     495        }
    591496    }
    592497
     
    597502     */
    598503    public boolean isActiveLayerVisible() {
    599         OsmDataLayer e = getEditLayer();
    600         return e != null && e.isVisible();
     504        synchronized (layers) {
     505            return isActiveLayerDrawable() && editLayer.isVisible();
     506        }
    601507    }
    602508
     
    609515     *   <li>otherwise, the top most layer of any type becomes active</li>
    610516     * </ul>
    611      * To be removed: end of 2016 (now handled by {@link LayerManagerWithActive}
    612517     * @param layersList lit of layers
    613518     *
    614519     * @return the next active data layer
    615520     */
    616     @Deprecated
    617521    protected Layer determineNextActiveLayer(List<Layer> layersList) {
    618522        // First look for data layer
     
    628532        // and then give up
    629533        return null;
     534
    630535    }
    631536
     
    633538     * Remove the layer from the mapview. If the layer was in the list before,
    634539     * an LayerChange event is fired.
    635      * <p>
    636      * Use {@link Main#getLayerManager()}.removeLayer() instead. To be removed: end of 2016.
    637540     * @param layer The layer to remove
    638541     */
    639     @Deprecated
    640542    public void removeLayer(Layer layer) {
    641         layerManager.removeLayer(layer);
    642     }
    643 
    644     @Override
    645     public void layerRemoving(LayerRemoveEvent e) {
    646         Layer layer = e.getRemovedLayer();
    647         if (layer instanceof OsmDataLayer) {
    648             ((OsmDataLayer) layer).removeLayerPropertyChangeListener(this);
    649         }
    650 
    651         Main.removeProjectionChangeListener(layer);
    652         layer.removePropertyChangeListener(this);
    653         invalidatedListener.removeFrom(layer);
    654         layer.destroy();
    655         AudioPlayer.reset();
     543        EnumSet<LayerListenerType> listenersToFire = EnumSet.noneOf(LayerListenerType.class);
     544        Layer oldActiveLayer = activeLayer;
     545        OsmDataLayer oldEditLayer = editLayer;
     546
     547        synchronized (layers) {
     548            List<Layer> layersList = new ArrayList<>(layers);
     549
     550            if (!layersList.remove(layer))
     551                return;
     552
     553            listenersToFire = setEditLayer(layersList);
     554
     555            if (layer == activeLayer) {
     556                listenersToFire.addAll(setActiveLayer(determineNextActiveLayer(layersList), false));
     557            }
     558
     559            if (layer instanceof OsmDataLayer) {
     560                ((OsmDataLayer) layer).removeLayerPropertyChangeListener(this);
     561            }
     562
     563            layers.remove(layer);
     564            Main.removeProjectionChangeListener(layer);
     565            layer.removePropertyChangeListener(this);
     566            invalidatedListener.removeFrom(layer);
     567            layer.destroy();
     568            AudioPlayer.reset();
     569        }
     570        onActiveEditLayerChanged(oldActiveLayer, oldEditLayer, listenersToFire);
     571        fireLayerRemoved(layer);
    656572
    657573        repaint();
     574    }
     575
     576    private void onEditLayerChanged(OsmDataLayer oldEditLayer) {
     577        fireEditLayerChanged(oldEditLayer, editLayer);
     578        refreshTitle();
    658579    }
    659580
     
    684605     */
    685606    public void moveLayer(Layer layer, int pos) {
    686         layerManager.moveLayer(layer, pos);
    687     }
    688 
    689     @Override
    690     public void layerOrderChanged(LayerOrderChangeEvent e) {
    691         AudioPlayer.reset();
     607        EnumSet<LayerListenerType> listenersToFire;
     608        Layer oldActiveLayer = activeLayer;
     609        OsmDataLayer oldEditLayer = editLayer;
     610
     611        synchronized (layers) {
     612            int curLayerPos = layers.indexOf(layer);
     613            if (curLayerPos == -1)
     614                throw new IllegalArgumentException(tr("Layer not in list."));
     615            if (pos == curLayerPos)
     616                return; // already in place.
     617            layers.remove(curLayerPos);
     618            if (pos >= layers.size()) {
     619                layers.add(layer);
     620            } else {
     621                layers.add(pos, layer);
     622            }
     623            listenersToFire = setEditLayer(layers);
     624            AudioPlayer.reset();
     625        }
     626        onActiveEditLayerChanged(oldActiveLayer, oldEditLayer, listenersToFire);
     627
    692628        repaint();
    693629    }
     
    695631    /**
    696632     * Gets the index of the layer in the layer list.
    697      * <p>
    698      * Access the layer list using {@link Main#getLayerManager()} instead. To be removed: end of 2016.
    699633     * @param layer The layer to search for.
    700634     * @return The index in the list.
    701635     * @throws IllegalArgumentException if that layer does not belong to this view.
    702636     */
    703     @Deprecated
    704637    public int getLayerPos(Layer layer) {
    705         int curLayerPos = layerManager.getLayers().indexOf(layer);
     638        int curLayerPos;
     639        synchronized (layers) {
     640            curLayerPos = layers.indexOf(layer);
     641        }
    706642        if (curLayerPos == -1)
    707643            throw new IllegalArgumentException(tr("Layer not in list."));
    708644        return curLayerPos;
     645    }
     646
     647    /**
     648     * Creates a list of the visible layers in Z-Order, the layer with the lowest Z-Order
     649     * first, layer with the highest Z-Order last.
     650     * <p>
     651     * The active data layer is pulled above all adjacent data layers.
     652     *
     653     * @return a list of the visible in Z-Order, the layer with the lowest Z-Order
     654     * first, layer with the highest Z-Order last.
     655     */
     656    public List<Layer> getVisibleLayersInZOrder() {
     657        synchronized (layers) {
     658            List<Layer> ret = new ArrayList<>();
     659            // This is set while we delay the addition of the active layer.
     660            boolean activeLayerDelayed = false;
     661            for (ListIterator<Layer> iterator = layers.listIterator(layers.size()); iterator.hasPrevious();) {
     662                Layer l = iterator.previous();
     663                if (!l.isVisible()) {
     664                    // ignored
     665                } else if (l == activeLayer && l instanceof OsmDataLayer) {
     666                    // delay and add after the current block of OsmDataLayer
     667                    activeLayerDelayed = true;
     668                } else {
     669                    if (activeLayerDelayed && !(l instanceof OsmDataLayer)) {
     670                        // add active layer before the current one.
     671                        ret.add(activeLayer);
     672                        activeLayerDelayed = false;
     673                    }
     674                    // Add this layer now
     675                    ret.add(l);
     676                }
     677            }
     678            if (activeLayerDelayed) {
     679                ret.add(activeLayer);
     680            }
     681            return ret;
     682        }
    709683    }
    710684
     
    726700        }
    727701
    728         List<Layer> visibleLayers = layerManager.getVisibleLayersInZOrder();
     702        List<Layer> visibleLayers = getVisibleLayersInZOrder();
    729703
    730704        int nonChangedLayersCount = 0;
     
    919893
    920894    /**
    921      * Use {@link LayerManager#getLayers()} instead. To be removed: end of 2016.
    922      *
    923895     * @return An unmodifiable collection of all layers
    924896     */
    925     @Deprecated
    926897    public Collection<Layer> getAllLayers() {
    927         return layerManager.getLayers();
    928     }
    929 
    930     /**
    931      * Use {@link LayerManager#getLayers()} instead. To be removed: end of 2016.
    932      *
     898        synchronized (layers) {
     899            return Collections.unmodifiableCollection(new ArrayList<>(layers));
     900        }
     901    }
     902
     903    /**
    933904     * @return An unmodifiable ordered list of all layers
    934905     */
    935     @Deprecated
    936906    public List<Layer> getAllLayersAsList() {
    937         return layerManager.getLayers();
    938     }
    939 
    940     /**
    941      * Replies an unmodifiable list of layers of a certain type. To be removed: end of 2016.
     907        synchronized (layers) {
     908            return Collections.unmodifiableList(new ArrayList<>(layers));
     909        }
     910    }
     911
     912    /**
     913     * Replies an unmodifiable list of layers of a certain type.
    942914     *
    943915     * Example:
     
    945917     *     List&lt;WMSLayer&gt; wmsLayers = getLayersOfType(WMSLayer.class);
    946918     * </pre>
    947      * Use {@link LayerManager#getLayersOfType(Class)} instead.
    948      *
    949919     * @param <T> layer type
    950920     *
     
    952922     * @return an unmodifiable list of layers of a certain type.
    953923     */
    954     @Deprecated
    955924    public <T extends Layer> List<T> getLayersOfType(Class<T> ofType) {
    956         return layerManager.getLayersOfType(ofType);
    957     }
    958 
    959     /**
    960      * Replies the number of layers managed by this map view. To be removed: end of 2016.
    961      * <p>
    962      * You can use {@link Main#getLayerManager()}.getLayers().size() instead.
     925        return new ArrayList<>(Utils.filteredCollection(getAllLayers(), ofType));
     926    }
     927
     928    /**
     929     * Replies the number of layers managed by this map view
    963930     *
    964931     * @return the number of layers managed by this map view
    965932     */
    966     @Deprecated
    967933    public int getNumLayers() {
    968         return getAllLayers().size();
     934        synchronized (layers) {
     935            return layers.size();
     936        }
    969937    }
    970938
    971939    /**
    972940     * Replies true if there is at least one layer in this map view
    973      * <p>
    974      * You can use !{@link Main#getLayerManager()}.getLayers().isEmpty() instead.
    975941     *
    976942     * @return true if there is at least one layer in this map view
    977943     */
    978     @Deprecated
    979944    public boolean hasLayers() {
    980945        return getNumLayers() > 0;
     
    982947
    983948    /**
     949     * Sets the active edit layer.
     950     * <p>
     951     * @param layersList A list to select that layer from.
     952     * @return A list of change listeners that should be fired using {@link #onActiveEditLayerChanged(Layer, OsmDataLayer, EnumSet)}
     953     */
     954    private EnumSet<LayerListenerType> setEditLayer(List<Layer> layersList) {
     955        final OsmDataLayer newEditLayer = findNewEditLayer(layersList);
     956
     957        // Set new edit layer
     958        if (newEditLayer != editLayer) {
     959            if (newEditLayer == null) {
     960                // Note: Unsafe to call while layer write lock is held.
     961                getCurrentDataSet().setSelected();
     962            }
     963
     964            editLayer = newEditLayer;
     965            return EnumSet.of(LayerListenerType.EDIT_LAYER_CHANGE);
     966        } else {
     967            return EnumSet.noneOf(LayerListenerType.class);
     968        }
     969
     970    }
     971
     972    private OsmDataLayer findNewEditLayer(List<Layer> layersList) {
     973        OsmDataLayer newEditLayer = layersList.contains(editLayer) ? editLayer : null;
     974        // Find new edit layer
     975        if (activeLayer != editLayer || !layersList.contains(editLayer)) {
     976            if (activeLayer instanceof OsmDataLayer && layersList.contains(activeLayer)) {
     977                newEditLayer = (OsmDataLayer) activeLayer;
     978            } else {
     979                for (Layer layer:layersList) {
     980                    if (layer instanceof OsmDataLayer) {
     981                        newEditLayer = (OsmDataLayer) layer;
     982                        break;
     983                    }
     984                }
     985            }
     986        }
     987        return newEditLayer;
     988    }
     989
     990    /**
    984991     * Sets the active layer to <code>layer</code>. If <code>layer</code> is an instance
    985      * of {@link OsmDataLayer} also sets editLayer to <code>layer</code>.
    986      * <p>
    987      * You can use !{@link Main#getLayerManager()}.setActiveLayer() instead.
     992     * of {@link OsmDataLayer} also sets {@link #editLayer} to <code>layer</code>.
    988993     *
    989994     * @param layer the layer to be activate; must be one of the layers in the list of layers
    990995     * @throws IllegalArgumentException if layer is not in the list of layers
    991996     */
    992     @Deprecated
    993997    public void setActiveLayer(Layer layer) {
    994         layerManager.setActiveLayer(layer);
    995     }
     998        EnumSet<LayerListenerType> listenersToFire;
     999        Layer oldActiveLayer;
     1000        OsmDataLayer oldEditLayer;
     1001
     1002        synchronized (layers) {
     1003            oldActiveLayer = activeLayer;
     1004            oldEditLayer = editLayer;
     1005            listenersToFire = setActiveLayer(layer, true);
     1006        }
     1007        onActiveEditLayerChanged(oldActiveLayer, oldEditLayer, listenersToFire);
     1008
     1009        repaint();
     1010    }
     1011
     1012    /**
     1013     * Sets the active layer. Propagates this change to all map buttons.
     1014     * @param layer The layer to be active.
     1015     * @param setEditLayer if this is <code>true</code>, the edit layer is also set.
     1016     * @return A list of change listeners that should be fired using {@link #onActiveEditLayerChanged(Layer, OsmDataLayer, EnumSet)}
     1017     */
     1018    private EnumSet<LayerListenerType> setActiveLayer(final Layer layer, boolean setEditLayer) {
     1019        if (layer != null && !layers.contains(layer))
     1020            throw new IllegalArgumentException(tr("Layer ''{0}'' must be in list of layers", layer.toString()));
     1021
     1022        if (layer == activeLayer)
     1023            return EnumSet.noneOf(LayerListenerType.class);
     1024
     1025        activeLayer = layer;
     1026        EnumSet<LayerListenerType> listenersToFire = EnumSet.of(LayerListenerType.ACTIVE_LAYER_CHANGE);
     1027        if (setEditLayer) {
     1028            listenersToFire.addAll(setEditLayer(layers));
     1029        }
     1030
     1031        return listenersToFire;
     1032    }
     1033
    9961034    /**
    9971035     * Replies the currently active layer
    998      * <p>
    999      * You can use !{@link Main#getLayerManager()}.getActiveLayer() instead.
    10001036     *
    10011037     * @return the currently active layer (may be null)
    10021038     */
    1003     @Deprecated
    10041039    public Layer getActiveLayer() {
    1005         return layerManager.getActiveLayer();
    1006     }
    1007 
    1008     @Override
    1009     public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) {
     1040        synchronized (layers) {
     1041            return activeLayer;
     1042        }
     1043    }
     1044
     1045    private enum LayerListenerType {
     1046        ACTIVE_LAYER_CHANGE,
     1047        EDIT_LAYER_CHANGE
     1048    }
     1049
     1050    /**
     1051     * This is called whenever one of active layer/edit layer or both may have been changed,
     1052     * @param oldActive The old active layer
     1053     * @param oldEdit The old edit layer.
     1054     * @param listenersToFire A mask of listeners to fire using {@link LayerListenerType}s
     1055     */
     1056    private void onActiveEditLayerChanged(final Layer oldActive, final OsmDataLayer oldEdit, EnumSet<LayerListenerType> listenersToFire) {
     1057        if (listenersToFire.contains(LayerListenerType.EDIT_LAYER_CHANGE)) {
     1058            onEditLayerChanged(oldEdit);
     1059        }
     1060        if (listenersToFire.contains(LayerListenerType.ACTIVE_LAYER_CHANGE)) {
     1061            onActiveLayerChanged(oldActive);
     1062        }
     1063    }
     1064
     1065    private void onActiveLayerChanged(final Layer old) {
     1066        fireActiveLayerChanged(old, activeLayer);
     1067
    10101068        /* This only makes the buttons look disabled. Disabling the actions as well requires
    10111069         * the user to re-select the tool after i.e. moving a layer. While testing I found
     
    10141072        for (final AbstractButton b: Main.map.allMapModeButtons) {
    10151073            MapMode mode = (MapMode) b.getAction();
    1016             final boolean activeLayerSupported = mode.layerIsSupported(layerManager.getActiveLayer());
     1074            final boolean activeLayerSupported = mode.layerIsSupported(activeLayer);
    10171075            if (activeLayerSupported) {
    10181076                Main.registerActionShortcut(mode, mode.getShortcut()); //fix #6876
     
    10271085        }
    10281086        AudioPlayer.reset();
    1029         refreshTitle();
    10301087        repaint();
    10311088    }
     
    10331090    /**
    10341091     * Replies the current edit layer, if any
    1035      * <p>
    1036      * You can use !{@link Main#getLayerManager()}.getEditLayer() instead. To be made private: end of 2016.
    10371092     *
    10381093     * @return the current edit layer. May be null.
    10391094     */
    1040     @Deprecated
    10411095    public OsmDataLayer getEditLayer() {
    1042         return layerManager.getEditLayer();
     1096        synchronized (layers) {
     1097            return editLayer;
     1098        }
    10431099    }
    10441100
    10451101    /**
    10461102     * replies true if the list of layers managed by this map view contain layer
    1047      * <p>
    1048      * You can use !{@link Main#getLayerManager()}.containsLayer() instead.
    10491103     *
    10501104     * @param layer the layer
    10511105     * @return true if the list of layers managed by this map view contain layer
    10521106     */
    1053     @Deprecated
    10541107    public boolean hasLayer(Layer layer) {
    1055         return layerManager.containsLayer(layer);
     1108        synchronized (layers) {
     1109            return layers.contains(layer);
     1110        }
    10561111    }
    10571112
     
    11251180    protected void refreshTitle() {
    11261181        if (Main.parent != null) {
    1127             OsmDataLayer editLayer = layerManager.getEditLayer();
    1128             boolean dirty = editLayer != null &&
    1129                     (editLayer.requiresSaveToFile() || (editLayer.requiresUploadToServer() && !editLayer.isUploadDiscouraged()));
    1130             ((JFrame) Main.parent).setTitle((dirty ? "* " : "") + tr("Java OpenStreetMap Editor"));
    1131             ((JFrame) Main.parent).getRootPane().putClientProperty("Window.documentModified", dirty);
     1182            synchronized (layers) {
     1183                boolean dirty = editLayer != null &&
     1184                        (editLayer.requiresSaveToFile() || (editLayer.requiresUploadToServer() && !editLayer.isUploadDiscouraged()));
     1185                ((JFrame) Main.parent).setTitle((dirty ? "* " : "") + tr("Java OpenStreetMap Editor"));
     1186                ((JFrame) Main.parent).getRootPane().putClientProperty("Window.documentModified", dirty);
     1187            }
    11321188        }
    11331189    }
     
    11481204
    11491205    public void destroy() {
    1150         layerManager.removeLayerChangeListener(this);
    1151         layerManager.removeActiveLayerChangeListener(this);
    11521206        Main.pref.removePreferenceChangeListener(this);
    11531207        DataSet.removeSelectionListener(repaintSelectionChangedListener);
     
    11561210            mapMover.destroy();
    11571211        }
    1158         nonChangedLayers.clear();
     1212        synchronized (layers) {
     1213            activeLayer = null;
     1214            changedLayer = null;
     1215            editLayer = null;
     1216            layers.clear();
     1217            nonChangedLayers.clear();
     1218        }
    11591219        synchronized (temporaryLayers) {
    11601220            temporaryLayers.clear();
     
    11641224    @Override
    11651225    public void uploadDiscouragedChanged(OsmDataLayer layer, boolean newValue) {
    1166         if (layer == layerManager.getEditLayer()) {
     1226        if (layer == getEditLayer()) {
    11671227            refreshTitle();
    11681228        }
  • trunk/src/org/openstreetmap/josm/gui/layer/LayerPositionStrategy.java

    r10274 r10270  
    44import java.util.List;
    55
     6import org.openstreetmap.josm.gui.MapView;
    67import org.openstreetmap.josm.tools.Predicate;
    78import org.openstreetmap.josm.tools.Predicates;
     
    1920    public static final LayerPositionStrategy IN_FRONT = new LayerPositionStrategy() {
    2021        @Override
    21         public int getPosition(LayerManager manager) {
     22        public int getPosition(MapView manager) {
    2223            return 0;
    2324        }
     
    7273        return new LayerPositionStrategy() {
    7374            @Override
    74             public int getPosition(LayerManager manager) {
    75                 List<Layer> layers = manager.getLayers();
     75            public int getPosition(MapView manager) {
     76                List<Layer> layers = manager.getAllLayersAsList();
    7677                for (int i = 0; i < layers.size(); i++) {
    7778                    if (what.evaluate(layers.get(i))) {
     
    9293        return new LayerPositionStrategy() {
    9394            @Override
    94             public int getPosition(LayerManager manager) {
    95                 List<Layer> layers = manager.getLayers();
     95            public int getPosition(MapView manager) {
     96                List<Layer> layers = manager.getAllLayersAsList();
    9697                for (int i = layers.size() - 1; i >= 0; i--) {
    9798                    if (what.evaluate(layers.get(i))) {
     
    109110     * @return The position in the range 0...layers.size
    110111     */
    111     public abstract int getPosition(LayerManager manager);
     112    public abstract int getPosition(MapView manager);
    112113}
  • trunk/src/org/openstreetmap/josm/gui/util/GuiHelper.java

    r10274 r10270  
    131131
    132132    /**
    133      * Executes synchronously a runnable in
    134      * <a href="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html">Event Dispatch Thread</a>.
    135      * <p>
    136      * Passes on the exception that was thrown to the thread calling this. The exception is wrapped in a {@link RuntimeException} if it was a normal {@link Throwable}.
    137      * @param task The runnable to execute
    138      * @see SwingUtilities#invokeAndWait
    139      * @since 10271
    140      */
    141     public static void runInEDTAndWaitWithException(Runnable task) {
    142         if (SwingUtilities.isEventDispatchThread()) {
    143             task.run();
    144         } else {
    145             try {
    146                 SwingUtilities.invokeAndWait(task);
    147             } catch (InterruptedException e) {
    148                 Main.error(e);
    149             } catch (InvocationTargetException e) {
    150                 if (e.getCause() instanceof RuntimeException) {
    151                     throw (RuntimeException) e.getCause();
    152                 } else {
    153                     throw new RuntimeException("Exception while clling " + task, e.getCause());
    154                 }
    155             }
    156         }
    157     }
    158 
    159     /**
    160133     * Executes synchronously a callable in
    161134     * <a href="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html">Event Dispatch Thread</a>
     
    183156                return null;
    184157            }
    185         }
    186     }
    187 
    188     /**
    189      * This function fails if it was not called from the EDT thread.
    190      * @throws IllegalStateException if called from wrong thread.
    191      * @since 10271
    192      */
    193     public static void assertCallFromEdt() {
    194         if (!SwingUtilities.isEventDispatchThread()) {
    195             throw new IllegalStateException(
    196                     "Needs to be called from the EDT thread, not from " + Thread.currentThread().getName());
    197158        }
    198159    }
Note: See TracChangeset for help on using the changeset viewer.