Index: /trunk/src/org/openstreetmap/josm/data/osm/DataSet.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 12013)
+++ /trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 12014)
@@ -50,4 +50,5 @@
 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionManager;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
+import org.openstreetmap.josm.tools.ListenerList;
 import org.openstreetmap.josm.tools.SubclassFilteredCollection;
 import org.openstreetmap.josm.tools.Utils;
@@ -156,4 +157,5 @@
     private Collection<WaySegment> highlightedVirtualNodes = new LinkedList<>();
     private Collection<WaySegment> highlightedWaySegments = new LinkedList<>();
+    private final ListenerList<HighlightUpdateListener> highlightUpdateListeners = ListenerList.create();
 
     // Number of open calls to beginUpdate
@@ -161,6 +163,4 @@
     // Events that occurred while dataset was locked but should be fired after write lock is released
     private final List<AbstractDatasetChangedEvent> cachedEvents = new ArrayList<>();
-
-    private int highlightUpdateCount;
 
     private UploadPolicy uploadPolicy;
@@ -267,13 +267,4 @@
     public Lock getReadLock() {
         return lock.readLock();
-    }
-
-    /**
-     * This method can be used to detect changes in highlight state of primitives. If highlighting was changed
-     * then the method will return different number.
-     * @return the current highlight counter
-     */
-    public int getHighlightUpdateCount() {
-        return highlightUpdateCount;
     }
 
@@ -726,4 +717,22 @@
     public Collection<WaySegment> getHighlightedWaySegments() {
         return Collections.unmodifiableCollection(highlightedWaySegments);
+    }
+
+    /**
+     * Adds a listener that gets notified whenever way segment / virtual nodes highlights change.
+     * @param listener The Listener
+     * @since 12014
+     */
+    public void addHighlightUpdateListener(HighlightUpdateListener listener) {
+        highlightUpdateListeners.addListener(listener);
+    }
+
+    /**
+     * Removes a listener that was added with {@link #addHighlightUpdateListener(HighlightUpdateListener)}
+     * @param listener The Listener
+     * @since 12014
+     */
+    public void removeHighlightUpdateListener(HighlightUpdateListener listener) {
+        highlightUpdateListeners.removeListener(listener);
     }
 
@@ -1335,5 +1344,6 @@
 
     void fireHighlightingChanged() {
-        highlightUpdateCount++;
+        HighlightUpdateListener.HighlightUpdateEvent e = new HighlightUpdateListener.HighlightUpdateEvent(this);
+        highlightUpdateListeners.fireEvent(l -> l.highlightUpdated(e));
     }
 
Index: /trunk/src/org/openstreetmap/josm/data/osm/HighlightUpdateListener.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/HighlightUpdateListener.java	(revision 12014)
+++ /trunk/src/org/openstreetmap/josm/data/osm/HighlightUpdateListener.java	(revision 12014)
@@ -0,0 +1,42 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.osm;
+
+/**
+ * This is a listener that listens to highlight segment changes.
+ * @author Michael Zangl
+ * @since 12014
+ */
+@FunctionalInterface
+public interface HighlightUpdateListener {
+
+    /**
+     * An event that is fired whenever highlighting on the OSM {@link DataSet} changed.
+     * @author Michael Zangl
+     * @since 12014
+     */
+    public class HighlightUpdateEvent {
+        private final DataSet dataSet;
+
+        /**
+         * Create a new highlight update event.
+         * @param dataSet The dataset that was changed.
+         */
+        public HighlightUpdateEvent(DataSet dataSet) {
+            this.dataSet = dataSet;
+        }
+
+        /**
+         * Get the modified data set.
+         * @return The data set.
+         */
+        public DataSet getDataSet() {
+            return dataSet;
+        }
+    }
+
+    /**
+     * Called whenever the highlighting of way segments in the dataset changed.
+     * @param e The dataset highlight event.
+     */
+    void highlightUpdated(HighlightUpdateEvent e);
+}
Index: /trunk/src/org/openstreetmap/josm/gui/layer/AbstractMapViewPaintable.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/AbstractMapViewPaintable.java	(revision 12013)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/AbstractMapViewPaintable.java	(revision 12014)
@@ -88,4 +88,5 @@
     /**
      * This needs to be called whenever the content of this view was invalidated.
+     * It triggers a repaint of the components that display this layer.
      */
     public void invalidate() {
Index: /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 12013)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 12014)
@@ -66,4 +66,5 @@
 import org.openstreetmap.josm.data.osm.DataSetMerger;
 import org.openstreetmap.josm.data.osm.DatasetConsistencyTest;
+import org.openstreetmap.josm.data.osm.HighlightUpdateListener;
 import org.openstreetmap.josm.data.osm.IPrimitive;
 import org.openstreetmap.josm.data.osm.Node;
@@ -117,5 +118,5 @@
  * @since 17
  */
-public class OsmDataLayer extends AbstractModifiableLayer implements Listener, SelectionChangedListener {
+public class OsmDataLayer extends AbstractModifiableLayer implements Listener, SelectionChangedListener, HighlightUpdateListener {
     private static final int HATCHED_SIZE = 15;
     /** Property used to know if this layer has to be saved on disk */
@@ -126,5 +127,4 @@
     private boolean requiresSaveToFile;
     private boolean requiresUploadToServer;
-    private int highlightUpdateCount;
 
     /**
@@ -364,4 +364,5 @@
         data.addDataSetListener(new DataSetListenerAdapter(this));
         data.addDataSetListener(MultipolygonCache.getInstance());
+        data.addHighlightUpdateListener(this);
         DataSet.addSelectionListener(this);
         if (name != null && name.startsWith(createLayerName("")) && Character.isDigit(
@@ -400,6 +401,4 @@
      */
     @Override public void paint(final Graphics2D g, final MapView mv, Bounds box) {
-        highlightUpdateCount = data.getHighlightUpdateCount();
-
         boolean active = mv.getLayerManager().getActiveLayer() == this;
         boolean inactive = !active && Main.pref.getBoolean("draw.data.inactive_color", true);
@@ -908,9 +907,4 @@
 
     @Override
-    public boolean isChanged() {
-        return highlightUpdateCount != data.getHighlightUpdateCount();
-    }
-
-    @Override
     public void onPostSaveToFile() {
         setRequiresSaveToFile(false);
@@ -952,4 +946,5 @@
         super.destroy();
         DataSet.removeSelectionListener(this);
+        data.removeHighlightUpdateListener(this);
     }
 
@@ -1102,3 +1097,8 @@
         return v.getBounds();
     }
+
+    @Override
+    public void highlightUpdated(HighlightUpdateEvent e) {
+        invalidate();
+    }
 }
