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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.