Ticket #13095: patch-mapview-add-layer-presence-event.patch

File patch-mapview-add-layer-presence-event.patch, 8.4 KB (added by michael2402, 8 years ago)
  • src/org/openstreetmap/josm/gui/MainApplication.java

    diff --git a/src/org/openstreetmap/josm/gui/MainApplication.java b/src/org/openstreetmap/josm/gui/MainApplication.java
    index 4abcbe5..15dd555 100644
    a b public class MainApplication extends Main {  
    396396
    397397        I18n.setupLanguageFonts();
    398398
    399         // Can only be called after preferences are initialized.
    400         // We can move this to MainPanel constructor as soon as noone depends on Main#panel any more.
    401         GuiHelper.runInEDTAndWait(new Runnable() {
    402             @Override
    403             public void run() {
    404                 mainPanel.updateContent();
    405             }
    406         });
    407 
    408399        WindowGeometry geometry = WindowGeometry.mainWindow("gui.geometry",
    409400                args.containsKey(Option.GEOMETRY) ? args.get(Option.GEOMETRY).iterator().next() : null,
    410401                !args.containsKey(Option.NO_MAXIMIZE) && Main.pref.getBoolean("gui.maximized", false));
  • src/org/openstreetmap/josm/gui/MainPanel.java

    diff --git a/src/org/openstreetmap/josm/gui/MainPanel.java b/src/org/openstreetmap/josm/gui/MainPanel.java
    index 0762e3b..f7ffd64 100644
    a b import java.util.List;  
    66import java.util.concurrent.CopyOnWriteArrayList;
    77
    88import javax.swing.JPanel;
    9 import javax.swing.SwingUtilities;
    109
    1110import org.openstreetmap.josm.Main;
    1211import org.openstreetmap.josm.actions.mapmode.MapMode;
    1312import org.openstreetmap.josm.gui.layer.Layer;
    14 import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent;
    15 import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener;
    16 import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent;
    17 import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
    1813import org.openstreetmap.josm.gui.layer.MainLayerManager;
     14import org.openstreetmap.josm.gui.layer.MainLayerManager.LayerAvailabilityEvent;
     15import org.openstreetmap.josm.gui.layer.MainLayerManager.LayerAvailabilityListener;
    1916import org.openstreetmap.josm.gui.util.GuiHelper;
    2017
    2118/**
    public class MainPanel extends JPanel {  
    4441
    4542    /**
    4643     * Update the content of this {@link MainFrame} to either display the map or display the welcome screen.
     44     * @param showMap If the map should be displayed.
    4745     */
    48     protected void updateContent() {
     46    protected void updateContent(boolean showMap) {
    4947        GuiHelper.assertCallFromEdt();
    5048        MapFrame old = map;
    51         boolean showMap = !layerManager.getLayers().isEmpty();
    5249        if (old != null && showMap) {
    5350            // no state change
    5451            return;
    public class MainPanel extends JPanel {  
    154151     * Re-adds the layer listeners. Never call this in production, only needed for testing.
    155152     */
    156153    public void reAddListeners() {
    157         layerManager.addLayerChangeListener(new LayerChangeListener() {
     154        layerManager.addLayerAvailabilityListener(new LayerAvailabilityListener() {
    158155            @Override
    159             public void layerAdded(LayerAddEvent e) {
    160                 updateContent();
     156            public void beforeFirstLayerAdded(LayerAvailabilityEvent e) {
     157                updateContent(true);
    161158            }
    162159
    163160            @Override
    164             public void layerRemoving(final LayerRemoveEvent e) {
    165                 // Delay main.map removal until after all listeners are finished.
    166                 // Some components rely on this and e.g. get the MapView that way.
    167                 SwingUtilities.invokeLater(new Runnable() {
    168                     @Override
    169                     public void run() {
    170                         updateContent();
    171                     }
    172                 });
     161            public void afterLastLayerRemoved(LayerAvailabilityEvent e) {
     162                updateContent(false);
    173163            }
    174 
     164        });
     165        GuiHelper.runInEDTAndWait(new Runnable() {
    175166            @Override
    176             public void layerOrderChanged(LayerOrderChangeEvent e) {
    177                 // ignored
     167            public void run() {
     168                updateContent(!layerManager.getLayers().isEmpty());
    178169            }
    179170        });
    180171    }
  • src/org/openstreetmap/josm/gui/layer/MainLayerManager.java

    diff --git a/src/org/openstreetmap/josm/gui/layer/MainLayerManager.java b/src/org/openstreetmap/josm/gui/layer/MainLayerManager.java
    index bd6a5ee..442a47d 100644
    a b public class MainLayerManager extends LayerManager {  
    9494    }
    9595
    9696    /**
     97     * This event is fired for {@link LayerAvailabilityListener}
     98     * @author Michael Zangl
     99     * @since  xxx
     100     */
     101    public class LayerAvailabilityEvent extends LayerManagerEvent {
     102        private final boolean hasLayers;
     103
     104        LayerAvailabilityEvent(LayerManager source, boolean hasLayers) {
     105            super(source);
     106            this.hasLayers = hasLayers;
     107        }
     108
     109        /**
     110         * Checks if this layer manager will have layers afterwards
     111         * @return true if layers will be added.
     112         */
     113        public boolean hasLayers() {
     114            return hasLayers;
     115        }
     116    }
     117
     118    /**
     119     * A listener that gets informed before any layer is displayed and after all layers are removed.
     120     * @author Michael Zangl
     121     * @since xxx
     122     */
     123    public interface LayerAvailabilityListener {
     124        /**
     125         * This method is called in the UI thread right before the first layer is added.
     126         * @param e The event.
     127         */
     128        void beforeFirstLayerAdded(LayerAvailabilityEvent e);
     129
     130        /**
     131         * This method is called in the UI thread after the last layer was removed.
     132         * @param e The event.
     133         */
     134        void afterLastLayerRemoved(LayerAvailabilityEvent e);
     135    }
     136
     137    /**
    97138     * The layer from the layers list that is currently active.
    98139     */
    99140    private Layer activeLayer;
    public class MainLayerManager extends LayerManager {  
    104145    private OsmDataLayer editLayer;
    105146
    106147    private final List<ActiveLayerChangeListener> activeLayerChangeListeners = new CopyOnWriteArrayList<>();
     148    private final List<LayerAvailabilityListener> layerAvailabilityListeners = new CopyOnWriteArrayList<>();
    107149
    108150    /**
    109151     * Adds a active/edit layer change listener
    public class MainLayerManager extends LayerManager {  
    155197    }
    156198
    157199    /**
     200     * Add a new {@link LayerAvailabilityListener}.
     201     * @param listener The listener
     202     * @since xxx
     203     */
     204    public synchronized void addLayerAvailabilityListener(LayerAvailabilityListener listener) {
     205        if (!layerAvailabilityListeners.add(listener)) {
     206            throw new IllegalArgumentException("Attempted to add listener that was already in list: " + listener);
     207        }
     208    }
     209
     210    /**
     211     * Remove an {@link LayerAvailabilityListener}.
     212     * @param listener The listener
     213     * @since xxx
     214     */
     215    public synchronized void removeLayerAvailabilityListener(LayerAvailabilityListener listener) {
     216        if (!layerAvailabilityListeners.remove(listener)) {
     217            throw new IllegalArgumentException("Attempted to remove listener that was not in list: " + listener);
     218        }
     219
     220    }
     221
     222    /**
    158223     * Set the active layer. If the layer is an OsmDataLayer, the edit layer is also changed.
    159224     * @param layer The active layer.
    160225     */
    public class MainLayerManager extends LayerManager {  
    197262
    198263    @Override
    199264    protected synchronized void realAddLayer(Layer layer) {
     265        if (getLayers().isEmpty()) {
     266            LayerAvailabilityEvent e = new LayerAvailabilityEvent(this, true);
     267            for (LayerAvailabilityListener  l : layerAvailabilityListeners) {
     268                l.beforeFirstLayerAdded(e);
     269            }
     270        }
    200271        super.realAddLayer(layer);
    201272
    202273        // update the active layer automatically.
    public class MainLayerManager extends LayerManager {  
    213284        }
    214285
    215286        super.realRemoveLayer(layer);
     287
     288        if (getLayers().isEmpty()) {
     289            LayerAvailabilityEvent e = new LayerAvailabilityEvent(this, false);
     290            for (LayerAvailabilityListener  l : layerAvailabilityListeners) {
     291                l.afterLastLayerRemoved(e);
     292            }
     293        }
    216294    }
    217295
    218296    /**
    public class MainLayerManager extends LayerManager {  
    318396        super.resetState();
    319397
    320398        activeLayerChangeListeners.clear();
     399        layerAvailabilityListeners.clear();
    321400    }
    322401}