Changeset 10507 in josm for trunk/src/org


Ignore:
Timestamp:
2016-07-03T11:49:45+02:00 (8 years ago)
Author:
Don-vip
Message:

fix #13095 - Exception on closing layers (patch by michael2402) - gsoc-core

Location:
trunk/src/org/openstreetmap/josm
Files:
5 edited

Legend:

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

    r10498 r10507  
    658658            public void initialize() {
    659659                validator = new OsmValidator();
    660                 getLayerManager().addLayerChangeListener(validator);
    661660            }
    662661        });
  • trunk/src/org/openstreetmap/josm/data/validation/OsmValidator.java

    r10436 r10507  
    6060import org.openstreetmap.josm.data.validation.tests.WayConnectedToArea;
    6161import org.openstreetmap.josm.data.validation.tests.WronglyOrderedWays;
    62 import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent;
    63 import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener;
    64 import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent;
    65 import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
    66 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    6762import org.openstreetmap.josm.gui.layer.ValidatorLayer;
    6863import org.openstreetmap.josm.gui.preferences.projection.ProjectionPreference;
     
    7570 * @author Francisco R. Santos <frsantos@gmail.com>
    7671 */
    77 public class OsmValidator implements LayerChangeListener {
     72public class OsmValidator {
    7873
    7974    public static volatile ValidatorLayer errorLayer;
     
    346341    }
    347342
    348     /* -------------------------------------------------------------------------- */
    349     /* interface LayerChangeListener                                              */
    350     /* -------------------------------------------------------------------------- */
    351     @Override
    352     public void layerAdded(LayerAddEvent e) {
    353         // do nothing
    354     }
    355 
    356     @Override
    357     public void layerOrderChanged(LayerOrderChangeEvent e) {
    358         // do nothing
    359     }
    360 
    361     @Override
    362     public void layerRemoving(LayerRemoveEvent e) {
    363         if (e.getRemovedLayer() == errorLayer) {
    364             errorLayer = null;
    365             return;
    366         }
    367         if (e.getSource().getLayersOfType(OsmDataLayer.class).isEmpty()) {
    368             if (errorLayer != null) {
    369                 Main.getLayerManager().removeLayer(errorLayer);
    370             }
    371         }
    372     }
    373343}
  • trunk/src/org/openstreetmap/josm/gui/layer/LayerManager.java

    r10467 r10507  
    33
    44import java.util.ArrayList;
     5import java.util.Collection;
    56import java.util.Collections;
     7import java.util.IdentityHashMap;
     8import java.util.Iterator;
    69import java.util.List;
     10import java.util.Set;
    711import java.util.concurrent.CopyOnWriteArrayList;
    812
     
    98102        private final Layer removedLayer;
    99103        private final boolean lastLayer;
     104        private Collection<Layer> scheduleForRemoval = new ArrayList<>();
    100105
    101106        LayerRemoveEvent(LayerManager source, Layer removedLayer) {
     
    120125        public boolean isLastLayer() {
    121126            return lastLayer;
     127        }
     128
     129        /**
     130         * Schedule the removal of other layers after this layer has been deleted.
     131         * <p>
     132         * Dupplicate removal requests are ignored.
     133         * @param layers The layers to remove.
     134         * @since 10507
     135         */
     136        public void scheduleRemoval(Collection<? extends Layer> layers) {
     137            for (Layer layer : layers) {
     138                getSource().checkContainsLayer(layer);
     139            }
     140            scheduleForRemoval.addAll(layers);
    122141        }
    123142
     
    198217
    199218    protected synchronized void realRemoveLayer(Layer layer) {
    200         checkContainsLayer(layer);
    201 
    202         fireLayerRemoving(layer);
    203         layers.remove(layer);
     219        GuiHelper.assertCallFromEdt();
     220        Set<Layer> toRemove = Collections.newSetFromMap(new IdentityHashMap<Layer, Boolean>());
     221        toRemove.add(layer);
     222
     223        while (!toRemove.isEmpty()) {
     224            Iterator<Layer> iterator = toRemove.iterator();
     225            Layer layerToRemove = iterator.next();
     226            iterator.remove();
     227            checkContainsLayer(layerToRemove);
     228
     229            Collection<Layer> newToRemove = realRemoveSingleLayer(layerToRemove);
     230            toRemove.addAll(newToRemove);
     231        }
     232    }
     233
     234    protected Collection<Layer> realRemoveSingleLayer(Layer layerToRemove) {
     235        Collection<Layer> newToRemove = fireLayerRemoving(layerToRemove);
     236        layers.remove(layerToRemove);
     237        return newToRemove;
    204238    }
    205239
     
    334368    }
    335369
    336 
    337370    /**
    338371     * Removes a layer change listener
    339372     *
    340373     * @param listener the listener.
    341      * @param fireRemove if we should fire a remove event for every layer in this manager.
     374     * @param fireRemove if we should fire a remove event for every layer in this manager. The event is fired as if the layer was deleted but
     375     * {@link LayerRemoveEvent#scheduleRemoval(Collection)} is ignored.
    342376     */
    343377    public synchronized void removeLayerChangeListener(LayerChangeListener listener, boolean fireRemove) {
     
    365399    }
    366400
    367     private void fireLayerRemoving(Layer layer) {
     401    /**
     402     * Fire the layer remove event
     403     * @param layer The layer to remove
     404     * @return A list of layers that should be removed afterwards.
     405     */
     406    private Collection<Layer> fireLayerRemoving(Layer layer) {
    368407        GuiHelper.assertCallFromEdt();
    369408        LayerRemoveEvent e = new LayerRemoveEvent(this, layer);
     
    372411                l.layerRemoving(e);
    373412            } catch (RuntimeException t) {
    374                 throw BugReport.intercept(t).put("listener", l).put("event", e);
    375             }
    376         }
     413                throw BugReport.intercept(t).put("listener", l).put("event", e).put("layer", layer);
     414            }
     415        }
     416        return e.scheduleForRemoval;
    377417    }
    378418
  • trunk/src/org/openstreetmap/josm/gui/layer/MainLayerManager.java

    r10433 r10507  
    33
    44import java.util.ArrayList;
     5import java.util.Collection;
    56import java.util.List;
    67import java.util.ListIterator;
     
    207208
    208209    @Override
    209     protected synchronized void realRemoveLayer(Layer layer) {
     210    protected Collection<Layer> realRemoveSingleLayer(Layer layer) {
    210211        if (layer == activeLayer || layer == editLayer) {
    211212            Layer nextActive = suggestNextActiveLayer(layer);
     
    213214        }
    214215
    215         super.realRemoveLayer(layer);
     216        return super.realRemoveSingleLayer(layer);
    216217    }
    217218
  • trunk/src/org/openstreetmap/josm/gui/layer/ValidatorLayer.java

    r10453 r10507  
    55
    66import java.awt.Graphics2D;
     7import java.util.Collections;
    78import java.util.Enumeration;
    89import java.util.List;
     
    165166        // Removed layer is still in that list.
    166167        if (e.getRemovedLayer() instanceof OsmDataLayer && e.getSource().getLayersOfType(OsmDataLayer.class).size() <= 1) {
    167             Main.getLayerManager().removeLayer(this);
     168            e.scheduleRemoval(Collections.singleton(this));
    168169        } else if (e.getRemovedLayer() == this) {
    169170            Main.getLayerManager().removeLayerChangeListener(this);
Note: See TracChangeset for help on using the changeset viewer.