diff --git a/src/org/openstreetmap/josm/data/osm/DataSet.java b/src/org/openstreetmap/josm/data/osm/DataSet.java
index 608c9b5..4d24417 100644
|
a
|
b
|
public final class DataSet implements Data, Cloneable, ProjectionChangeListener
|
| 751 | 751 | return; |
| 752 | 752 | |
| 753 | 753 | highlightedVirtualNodes = waySegments; |
| 754 | | // can't use fireHighlightingChanged because it requires an OsmPrimitive |
| 755 | | highlightUpdateCount++; |
| | 754 | fireHighlightingChanged(); |
| 756 | 755 | } |
| 757 | 756 | |
| 758 | 757 | /** |
| … |
… |
public final class DataSet implements Data, Cloneable, ProjectionChangeListener
|
| 764 | 763 | return; |
| 765 | 764 | |
| 766 | 765 | highlightedWaySegments = waySegments; |
| 767 | | // can't use fireHighlightingChanged because it requires an OsmPrimitive |
| 768 | | highlightUpdateCount++; |
| | 766 | fireHighlightingChanged(); |
| 769 | 767 | } |
| 770 | 768 | |
| 771 | 769 | /** |
diff --git a/src/org/openstreetmap/josm/gui/MapView.java b/src/org/openstreetmap/josm/gui/MapView.java
index 9781528..8ea13ac 100644
|
a
|
b
|
import java.util.Arrays;
|
| 25 | 25 | import java.util.Collection; |
| 26 | 26 | import java.util.Collections; |
| 27 | 27 | import java.util.HashMap; |
| | 28 | import java.util.IdentityHashMap; |
| 28 | 29 | import java.util.LinkedHashSet; |
| 29 | 30 | import java.util.List; |
| 30 | 31 | import java.util.Set; |
| … |
… |
LayerManager.LayerChangeListener, MainLayerManager.ActiveLayerChangeListener {
|
| 147 | 148 | */ |
| 148 | 149 | private class LayerInvalidatedListener implements PaintableInvalidationListener { |
| 149 | 150 | private boolean ignoreRepaint; |
| | 151 | |
| | 152 | private final Set<MapViewPaintable> invalidatedLayers = Collections.newSetFromMap(new IdentityHashMap<MapViewPaintable, Boolean>()); |
| | 153 | |
| 150 | 154 | @Override |
| 151 | 155 | public void paintableInvalidated(PaintableInvalidationEvent event) { |
| | 156 | invalidate(event.getLayer()); |
| | 157 | } |
| | 158 | |
| | 159 | public synchronized void invalidate(MapViewPaintable mapViewPaintable) { |
| 152 | 160 | ignoreRepaint = true; |
| | 161 | invalidatedLayers.add(mapViewPaintable); |
| 153 | 162 | repaint(); |
| 154 | 163 | } |
| 155 | 164 | |
| … |
… |
LayerManager.LayerChangeListener, MainLayerManager.ActiveLayerChangeListener {
|
| 157 | 166 | * Temporary until all {@link MapViewPaintable}s support this. |
| 158 | 167 | * @param p The paintable. |
| 159 | 168 | */ |
| 160 | | public void addTo(MapViewPaintable p) { |
| | 169 | public synchronized void addTo(MapViewPaintable p) { |
| 161 | 170 | if (p instanceof AbstractMapViewPaintable) { |
| 162 | 171 | ((AbstractMapViewPaintable) p).addInvalidationListener(this); |
| 163 | 172 | } |
| … |
… |
LayerManager.LayerChangeListener, MainLayerManager.ActiveLayerChangeListener {
|
| 167 | 176 | * Temporary until all {@link MapViewPaintable}s support this. |
| 168 | 177 | * @param p The paintable. |
| 169 | 178 | */ |
| 170 | | public void removeFrom(MapViewPaintable p) { |
| | 179 | public synchronized void removeFrom(MapViewPaintable p) { |
| 171 | 180 | if (p instanceof AbstractMapViewPaintable) { |
| 172 | 181 | ((AbstractMapViewPaintable) p).removeInvalidationListener(this); |
| 173 | 182 | } |
| | 183 | invalidatedLayers.remove(p); |
| 174 | 184 | } |
| 175 | 185 | |
| 176 | 186 | /** |
| … |
… |
LayerManager.LayerChangeListener, MainLayerManager.ActiveLayerChangeListener {
|
| 183 | 193 | } |
| 184 | 194 | ignoreRepaint = false; |
| 185 | 195 | } |
| | 196 | |
| | 197 | /** |
| | 198 | * Retrives a set of all layers that have been marked as invalid since the last call to this method. |
| | 199 | * @return The layers |
| | 200 | */ |
| | 201 | protected synchronized Set<MapViewPaintable> collectInvalidatedLayers() { |
| | 202 | Set<MapViewPaintable> layers = Collections.newSetFromMap(new IdentityHashMap<MapViewPaintable, Boolean>()); |
| | 203 | layers.addAll(invalidatedLayers); |
| | 204 | invalidatedLayers.clear(); |
| | 205 | return layers; |
| | 206 | } |
| 186 | 207 | } |
| 187 | 208 | |
| 188 | 209 | /** |
| … |
… |
LayerManager.LayerChangeListener, MainLayerManager.ActiveLayerChangeListener {
|
| 503 | 524 | private transient BufferedImage offscreenBuffer; |
| 504 | 525 | // Layers that wasn't changed since last paint |
| 505 | 526 | private final transient List<Layer> nonChangedLayers = new ArrayList<>(); |
| 506 | | private transient Layer changedLayer; |
| 507 | 527 | private int lastViewID; |
| 508 | 528 | private boolean paintPreferencesChanged = true; |
| 509 | 529 | private Rectangle lastClipBounds = new Rectangle(); |
| … |
… |
LayerManager.LayerChangeListener, MainLayerManager.ActiveLayerChangeListener {
|
| 519 | 539 | */ |
| 520 | 540 | private final HashMap<Layer, LayerPainter> registeredLayers = new HashMap<>(); |
| 521 | 541 | |
| | 542 | |
| | 543 | |
| 522 | 544 | /** |
| 523 | 545 | * Constructs a new {@code MapView}. |
| 524 | 546 | * @param layerManager The layers to display. |
| … |
… |
LayerManager.LayerChangeListener, MainLayerManager.ActiveLayerChangeListener {
|
| 841 | 863 | List<Layer> visibleLayers = layerManager.getVisibleLayersInZOrder(); |
| 842 | 864 | |
| 843 | 865 | int nonChangedLayersCount = 0; |
| | 866 | Set<MapViewPaintable> invalidated = invalidatedListener.collectInvalidatedLayers(); |
| 844 | 867 | for (Layer l: visibleLayers) { |
| 845 | | if (l.isChanged() || l == changedLayer) { |
| | 868 | if (l.isChanged() || invalidated.contains(l)) { |
| 846 | 869 | break; |
| 847 | 870 | } else { |
| 848 | 871 | nonChangedLayersCount++; |
| … |
… |
LayerManager.LayerChangeListener, MainLayerManager.ActiveLayerChangeListener {
|
| 899 | 922 | } |
| 900 | 923 | |
| 901 | 924 | nonChangedLayers.clear(); |
| 902 | | changedLayer = null; |
| 903 | 925 | for (int i = 0; i < nonChangedLayersCount; i++) { |
| 904 | 926 | nonChangedLayers.add(visibleLayers.get(i)); |
| 905 | 927 | } |
| … |
… |
LayerManager.LayerChangeListener, MainLayerManager.ActiveLayerChangeListener {
|
| 1204 | 1226 | evt.getPropertyName().equals(Layer.FILTER_STATE_PROP)) { |
| 1205 | 1227 | Layer l = (Layer) evt.getSource(); |
| 1206 | 1228 | if (l.isVisible()) { |
| 1207 | | changedLayer = l; |
| 1208 | | repaint(); |
| | 1229 | invalidatedListener.invalidate(l); |
| 1209 | 1230 | } |
| 1210 | 1231 | } |
| 1211 | 1232 | } |
diff --git a/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java b/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java
index c26acdd..8faa3fc 100644
|
a
|
b
|
import javax.swing.JPanel;
|
| 50 | 50 | import javax.swing.JPopupMenu; |
| 51 | 51 | import javax.swing.JSeparator; |
| 52 | 52 | import javax.swing.JTextField; |
| | 53 | import javax.swing.Timer; |
| 53 | 54 | |
| 54 | 55 | import org.openstreetmap.gui.jmapviewer.AttributionSupport; |
| 55 | 56 | import org.openstreetmap.gui.jmapviewer.MemoryTileCache; |
| … |
… |
implements ImageObserver, TileLoaderListener, ZoomChangeListener, FilterChangeLi
|
| 136 | 137 | * Initial zoom lvl is set to bestZoom |
| 137 | 138 | */ |
| 138 | 139 | public int currentZoomLevel; |
| 139 | | private boolean needRedraw; |
| 140 | 140 | |
| 141 | 141 | private final AttributionSupport attribution = new AttributionSupport(); |
| 142 | 142 | private final TileHolder clickedTileHolder = new TileHolder(); |
| … |
… |
implements ImageObserver, TileLoaderListener, ZoomChangeListener, FilterChangeLi
|
| 158 | 158 | protected T tileSource; |
| 159 | 159 | protected TileLoader tileLoader; |
| 160 | 160 | |
| | 161 | /** |
| | 162 | * A timer that is used to delay invalidation events if required. |
| | 163 | */ |
| | 164 | private final Timer invalidateLaterTimer = new Timer(100, e -> this.invalidate()); |
| | 165 | |
| 161 | 166 | private final MouseAdapter adapter = new MouseAdapter() { |
| 162 | 167 | @Override |
| 163 | 168 | public void mouseClicked(MouseEvent e) { |
| … |
… |
implements ImageObserver, TileLoaderListener, ZoomChangeListener, FilterChangeLi
|
| 263 | 268 | tile.setImage(null); |
| 264 | 269 | } |
| 265 | 270 | tile.setLoaded(success); |
| 266 | | needRedraw = true; |
| 267 | | if (Main.map != null) { |
| 268 | | Main.map.repaint(100); |
| 269 | | } |
| | 271 | invalidateLater(); |
| 270 | 272 | if (Main.isDebugEnabled()) { |
| 271 | 273 | Main.debug("tileLoadingFinished() tile: " + tile + " success: " + success); |
| 272 | 274 | } |
| … |
… |
implements ImageObserver, TileLoaderListener, ZoomChangeListener, FilterChangeLi
|
| 296 | 298 | * @see #invalidate() To trigger a repaint of all places where the layer is displayed. |
| 297 | 299 | */ |
| 298 | 300 | protected void redraw() { |
| 299 | | needRedraw = true; |
| 300 | | if (isVisible()) Main.map.repaint(); |
| 301 | | } |
| 302 | | |
| 303 | | @Override |
| 304 | | public void invalidate() { |
| 305 | | needRedraw = true; |
| 306 | | super.invalidate(); |
| | 301 | invalidate(); |
| 307 | 302 | } |
| 308 | 303 | |
| 309 | 304 | /** |
| … |
… |
implements ImageObserver, TileLoaderListener, ZoomChangeListener, FilterChangeLi
|
| 1029 | 1024 | @Override |
| 1030 | 1025 | public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) { |
| 1031 | 1026 | boolean done = (infoflags & (ERROR | FRAMEBITS | ALLBITS)) != 0; |
| 1032 | | needRedraw = true; |
| 1033 | 1027 | if (Main.isDebugEnabled()) { |
| 1034 | 1028 | Main.debug("imageUpdate() done: " + done + " calling repaint"); |
| 1035 | 1029 | } |
| 1036 | | Main.map.repaint(done ? 0 : 100); |
| | 1030 | |
| | 1031 | if (done) { |
| | 1032 | invalidate(); |
| | 1033 | } else { |
| | 1034 | invalidateLater(); |
| | 1035 | } |
| 1037 | 1036 | return !done; |
| 1038 | 1037 | } |
| 1039 | 1038 | |
| | 1039 | /** |
| | 1040 | * Invalidate the layer at a time in the future so taht the user still sees the interface responsive. |
| | 1041 | */ |
| | 1042 | private void invalidateLater() { |
| | 1043 | GuiHelper.runInEDT(() -> { |
| | 1044 | if (!invalidateLaterTimer.isRunning()) { |
| | 1045 | invalidateLaterTimer.setRepeats(false); |
| | 1046 | invalidateLaterTimer.start(); |
| | 1047 | } |
| | 1048 | }); |
| | 1049 | } |
| | 1050 | |
| 1040 | 1051 | private boolean imageLoaded(Image i) { |
| 1041 | 1052 | if (i == null) |
| 1042 | 1053 | return false; |
| … |
… |
implements ImageObserver, TileLoaderListener, ZoomChangeListener, FilterChangeLi
|
| 1752 | 1763 | |
| 1753 | 1764 | @Override |
| 1754 | 1765 | public boolean isChanged() { |
| 1755 | | return needRedraw; |
| | 1766 | // we use #invalidate() |
| | 1767 | return false; |
| 1756 | 1768 | } |
| 1757 | 1769 | |
| 1758 | 1770 | /** |
| … |
… |
implements ImageObserver, TileLoaderListener, ZoomChangeListener, FilterChangeLi
|
| 1898 | 1910 | private void doPaint(MapViewGraphics graphics) { |
| 1899 | 1911 | ProjectionBounds pb = graphics.getClipBounds().getProjectionBounds(); |
| 1900 | 1912 | |
| 1901 | | needRedraw = false; // TEMPORARY |
| 1902 | | |
| 1903 | 1913 | drawInViewArea(graphics.getDefaultGraphics(), graphics.getMapView(), pb); |
| 1904 | 1914 | } |
| 1905 | 1915 | |
diff --git a/src/org/openstreetmap/josm/gui/layer/Layer.java b/src/org/openstreetmap/josm/gui/layer/Layer.java
index 7347110..f70f0d8 100644
|
a
|
b
|
public abstract class Layer extends AbstractMapViewPaintable implements Destroya
|
| 425 | 425 | * Check changed status of layer |
| 426 | 426 | * |
| 427 | 427 | * @return True if layer was changed since last paint |
| | 428 | * @deprecated This is not supported by multiple map views. |
| | 429 | * Fire an {@link #invalidate()} to trigger a repaint. |
| | 430 | * Let this method return false if you only use invalidation events. |
| 428 | 431 | */ |
| | 432 | @Deprecated |
| 429 | 433 | public boolean isChanged() { |
| 430 | 434 | return true; |
| 431 | 435 | } |