Index: /trunk/src/org/openstreetmap/josm/actions/SaveActionBase.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/SaveActionBase.java	(revision 17627)
+++ /trunk/src/org/openstreetmap/josm/actions/SaveActionBase.java	(revision 17628)
@@ -12,4 +12,5 @@
 import java.util.List;
 
+import javax.swing.ImageIcon;
 import javax.swing.JFileChooser;
 import javax.swing.JOptionPane;
@@ -19,4 +20,5 @@
 import org.openstreetmap.josm.gui.ExtendedDialog;
 import org.openstreetmap.josm.gui.MainApplication;
+import org.openstreetmap.josm.gui.Notification;
 import org.openstreetmap.josm.gui.io.importexport.FileExporter;
 import org.openstreetmap.josm.gui.layer.AbstractModifiableLayer;
@@ -25,4 +27,5 @@
 import org.openstreetmap.josm.gui.widgets.AbstractFileChooser;
 import org.openstreetmap.josm.spi.preferences.Config;
+import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
@@ -134,4 +137,7 @@
             return false;
 
+        ImageIcon icon = ImageProvider.get("save");
+        Notification savingNotification = new Notification(tr("Saving file {0}...", file.getName())).setIcon(icon);
+        GuiHelper.runInEDT(savingNotification::show);
         try {
             boolean exported = false;
@@ -169,4 +175,6 @@
         }
         addToFileOpenHistory(file);
+        Notification doneNotification = new Notification(tr("Successfully saved file {0}", file.getName())).setIcon(icon);
+        GuiHelper.runInEDT(() -> doneNotification.replaceExisting(savingNotification));
         return true;
     }
Index: /trunk/src/org/openstreetmap/josm/gui/Notification.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/Notification.java	(revision 17627)
+++ /trunk/src/org/openstreetmap/josm/gui/Notification.java	(revision 17628)
@@ -214,4 +214,13 @@
     }
 
+    /**
+     * Display the notification by replacing the given queued/displaying notification
+     * @param oldNotification the notification to replace
+     * @since 17628
+     */
+    public void replaceExisting(Notification oldNotification) {
+        NotificationManager.getInstance().replaceExistingNotification(oldNotification, this);
+    }
+
     private Object getContentTextOrComponent() {
         return content instanceof JTextComponent ? ((JTextComponent) content).getText() : content;
Index: /trunk/src/org/openstreetmap/josm/gui/NotificationManager.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/NotificationManager.java	(revision 17627)
+++ /trunk/src/org/openstreetmap/josm/gui/NotificationManager.java	(revision 17628)
@@ -92,5 +92,5 @@
      * @see Notification#show()
      */
-    public void showNotification(Notification note) {
+    void showNotification(Notification note) {
         synchronized (queue) {
             if (Objects.equals(note, currentNotification) || Objects.equals(note, queue.peekLast())) {
@@ -99,4 +99,21 @@
             }
             queue.add(note);
+            processQueue();
+        }
+    }
+
+    /**
+     * Show the given notification by replacing the given queued/displaying notification
+     * @param oldNotification the notification to replace
+     * @param newNotification the notification to show
+     */
+    void replaceExistingNotification(Notification oldNotification, Notification newNotification) {
+        synchronized (queue) {
+            if (Objects.equals(oldNotification, currentNotification)) {
+                stopHideTimer();
+            } else {
+                queue.remove(oldNotification);
+            }
+            showNotification(newNotification);
             processQueue();
         }
