# Nebenläufigkeit: GUI vs. KI



## snoop83 (6. Jun 2005)

Wir haben in unserem Software-Pratikum die Aufgabe, ein Mühlespiel zu programmieren. Das Projekt ist bereits sehr fortgeschritten, Netzwerk, Engine, KI etc. funktioniert soweit alles. Wir sind nun dabei, das Programm noch alltagstauglich zu machen. Dabei hapert es an einigen Stellen.

Ein Problem ist u.a. folgendes:
Die Steine haben wir als JLabel' dargestellt, die bekommen einfach IconImages aufgedrückt und stellen die Bilder dar. Für die Auswertung eines Klicks habe ich mir eine Klasse "ListenerSteineKlick" geschrieben:

```
public class ListenerSteineKlick extends MouseAdapter {
	public void mouseClicked(MouseEvent event) {
		....
		if (Anwendung.fenster.steingeklickt(steinnummer))
			Anwendung.fenster.spielfeldneuzeichnen(0,null);
		.....
		Anwendung.computer_spielzug();
	}
}
```

In der Methode steingeklickt(int) wird nun die Gültigkeit des Klicks ausgewertet und die Spieldaten bzw. die Engine aktualisiert. Wurde ein gültiger Zug ausgeführt, liefert steingeklickt(int) true zurück und das Spielfeld wird neu gezeichnet.

Am Ende wird jedes mal die Methode computer_spielzug() aufgerufen. Dort wird ein Zug der KI berechnet.

Bei der Klickbehandlung (d.h. in der Methode mouseClicked(event)) wird
1. Der Spielerzug ausgewertet
2. Das Spielfeld neu gezeichnet
3. Der KI-Zug berechnet
3.1 dort evtl. nochmal das Spielfed neu gezeichnet

Problem ist nun folgendes:
spielfeldneuzeichnen(int, IconImage) wird ausgeführt, also komplett durchlaufen. Da aber der Kontrollfluss VOR DEM Aufruf der KI nicht mehr zur GUI zurückkommt, sondern der Kontrollfluss vom MouseAdapter aktiv ist und es auch bleibt, werden die Aktualisierungen der GUI nicht angezeigt.

Gebe ich zwischendruch eine Dialogbox aus, so wird zum Kontrollfluss der GUI zurückgekehrt und das Spielfeld wird korrekt neu gezeichnet (vor dem KI-Zug sowie danach) ... gebe ich zwischendurch keine Dialogbox aus, so werden die Aktualisierungen der GUI erst nach dem KI-Zug *angezeigt*.

Meine Frage nun:
1. Gibt es einen Aufruf, der explizit dafür sorgt, dass das aktuelle Fenster (die aktive JFrame) neu gezeichnet, sprich aktualisiert wird?
2. Wie kann ich das Problem sonst umgehen?
3. Würde es Abhilfe schaffen, wenn ich mir einen weiteren MouseListener erschaffe und "computer_spielzug()" beim Loslassen der Maustaste aufrufe, so dass die GUI vorher auf jeden Fall aktualisiert wird?


----------



## Gast (17. Jun 2005)

also genau kann ich dir nicht helfen, da ich eher c/c++/c# progge, aber da gibt es eine Invalidate methode (an der Fensterklasse) die alles neu Zeichnen lässt. Vielleicht ist das bei Java ja genauso!


----------



## m@nu (17. Jun 2005)

wenn du in ein swing-GUI von "aussen" eingreifst, solltest du immer folgende variante verwenden:


```
SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                  // do what you need with your gui
            }
        });
```

dies hilft dir vielleicht. falls nicht, meld' dich nochma'


----------



## snoop83 (19. Jun 2005)

hm, zu spät .. hab div. Methoden zum Neuzeichnen der JFrame benutzt, keine brachte mich zum Erfolg. Der Ansatz von m@nu klingt allerdings sehr brauchbar.

Wir haben das nun so gelöst, dass die KI einfach über einen Timer verzögert aufgerufen wird .. das ganze ist nun sogar noch variabel über's Menü einstellbar (0,0 - 2,0 Sekunden) und klappt wunderbar


----------

