diff --git a/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/GuiModelCatalogCoordinator.java b/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/GuiModelCatalogCoordinator.java
index d50ef1d..636c524 100644
--- a/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/GuiModelCatalogCoordinator.java
+++ b/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/GuiModelCatalogCoordinator.java
@@ -5,6 +5,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function;
import org.apache.logging.log4j.LogManager;
@@ -35,6 +36,13 @@ import javafx.application.Platform;
* completed retrieval attempt, so later GUI layers can display the result.
*
*
+ * Parallele Abrufanfragen (z. B. durch schnellen Provider-Wechsel oder mehrfaches Klicken
+ * auf „Modelle neu laden") werden durch einen Generationszähler entschärft: Jede neue Anfrage
+ * erhöht den Zähler. Wenn das Ergebnis eines Hintergrund-Threads auf dem JavaFX-Thread
+ * verarbeitet wird, prüft der Coordinator, ob die Generationsnummer noch aktuell ist. Veraltete
+ * Ergebnisse (aus einer früheren Anfrage) werden verworfen, sodass stets nur das Ergebnis der
+ * jüngsten Anfrage in die Meldungsliste und die Feldcontainer geschrieben wird.
+ *
* The worker thread factory is injectable so tests can supply a synchronous or latch-guarded
* executor without spinning a real OS thread.
*
@@ -62,6 +70,14 @@ public final class GuiModelCatalogCoordinator {
private final Map fieldContainers =
new ConcurrentHashMap<>();
+ /**
+ * Generationszähler zur Erkennung veralteter Abruf-Ergebnisse.
+ * Wird bei jeder neuen Anfrage in {@link #triggerModelRetrieval} atomar erhöht.
+ * Hintergrund-Threads erfassen die Generation beim Start; auf dem JavaFX-Thread wird
+ * das Ergebnis verworfen, wenn die gespeicherte Generation nicht mehr aktuell ist.
+ */
+ private final AtomicLong retrievalGeneration = new AtomicLong(0);
+
/**
* Consumer that delivers the retrieval result. In production this wraps the call in
* {@code Platform.runLater}. In tests it can be replaced with a direct call so the result
@@ -144,12 +160,23 @@ public final class GuiModelCatalogCoordinator {
// Build the request from the current editor state.
ModelCatalogRequest request = buildRequest(family, providerState);
- LOG.info("GUI-Modellabruf: Modelllistenabruf für Provider '{}' gestartet.",
- family.getIdentifier());
+ // Generationsnummer erhöhen – laufende Hintergrund-Threads mit einer älteren
+ // Generationsnummer verwerfen ihr Ergebnis, sobald sie auf dem FX-Thread ankommen.
+ long currentGeneration = retrievalGeneration.incrementAndGet();
+
+ LOG.info("GUI-Modellabruf: Modelllistenabruf für Provider '{}' gestartet (Generation {}).",
+ family.getIdentifier(), currentGeneration);
Runnable task = () -> {
ModelCatalogResult result = modelCatalogPort.fetchAvailableModels(request);
resultDelivery.accept(() -> {
+ // Veraltetes Ergebnis verwerfen, wenn inzwischen eine neuere Anfrage gestartet wurde.
+ if (retrievalGeneration.get() != currentGeneration) {
+ LOG.debug("GUI-Modellabruf: Ergebnis für Provider '{}' verworfen"
+ + " (Generation {} ist nicht mehr aktuell).",
+ family.getIdentifier(), currentGeneration);
+ return;
+ }
applyResult(family, container, result, previousManualValue);
postResultCallback.run();
});