repaint() durch sleep() gestört?
-
Hallo! Mein Programm zur Simulation der Langton-Ameise nimmt langsam Form an.
http://home.arcor.de/snoopy222/langton.jpg (kleiner Screenshot)Wie man sieht gibt es drei Buttons. Bei Schritt geht die Ameise einen Schritt weiter, das klappt auch alles wie gewünscht.
Da das natürlich zu langweilig ist soll die Ameise auch automatisch laufen können (durch drücken von Start) bis man Pause drückt, aber natürlich mit einer gewissen Verzögerung, damit man auch was erkennt.
Dies geschieht in einer while-Schleife.Daher lasse ich das Programm schlafen, in Java geht das wohl nur durch Verwendung von Thread.sleep() wobei ich schätze das hier auch das Problem liegt:
Zwar führt das Programm alle Schritte der Ameise durch, jedoch hat der Aufruf der Repaint Funktion keinen Effekt. Die Graphik wird erst nachdem die Schleife terminiert, aktualisiert. Ich möchte natürlich nach jedem Schritt etwas sehen sonst ist es ja sinnlos.Es scheint also als ob das repaint keinen effekt hat, aufgrund des sleep().
Habe auch schon repaint(long) versucht.
Hier mein Code des Action Listeners der das realisiert:public void actionPerformed(ActionEvent ev){ if (ev.getActionCommand().equals("stepped")){ ameisenfeld.move(); System.out.println("action"); anzeigefeld.repaint(); } if (ev.getActionCommand().equals("paused")){ running=false; } if (ev.getActionCommand().equals("started")){ running=true; while(running){ anzeigefeld.repaint(1); if(-1==ameisenfeld.move()){ //Ameise läuft aus dem Feld! running=false; } try{ Thread.sleep(1); }catch(InterruptedException ie){ System.out.println("Interrupted Exception"); } } } }
-
Das neuzeichnen wird im event dispatching Thread durchgeführt und diesen legst du lahm, weil du genau bei events auf dem aktuellen (ebendiesen) Thread schläfst. Das darfste nicht machen.
Ich würde überhaupt niemals irgendwas langwierigeres (und sleep ist sehr langwierig) direkt im event-thread machen, weil das GUI dann so lange nicht mehr reagiert.
-
Ich kenne mich mit Java nicht aus, aber ich würde einen Timer nehmen.
-
Auf die Idee mit nem Timer bin ich noch gar net gekommen (hab auch noch nie einen gebraucht und mich damit noch nicht beschäftigt, werde das aber morgen mal tun), aber die Idee gefällt mir nicht schlecht.
Was die Threads angeht, um das zu verstehen: Würde es dann reichen die Datenverarbeitung (die das Datenmodell der Ameise und ihre Bewegung regelt) in einen eigenen Thread zu packen und diesen dann schlafen zu lassen? Wenn ich keine Events etc. mehr verwende sollte der "event dispatching Thread" dann nicht mehr betroffen sein oder?
ps. bin jetzt erst mal ne nacht drüber schlafen
achso (Nachtrag) eins verstehe ich noch nicht ganz von meinem Denken her:
Das die Buttons durch das Sleep nicht reagieren ist mir klar, aber da ich doch jedes mal nach dem Ende des sleep neu zeichne, wieso wird dies nicht ausgeführt?
Ich denke da anscheindend zu prozedural Kann mir das wer kurz darstellen?dankeschöön
-
Du läufst hier eine (mehr oder weniger) Endlosschleife auf dem Event-Thread. Ohne Garantie, dass das stimmt, ich glaube aber, dass man erst etwas sieht, wenn er wieder Events bearbeitet werden. Es gibt für sowas eigene Events im Windows-internen Kram, WM_PAINT oder so und wenn das nicht bearbeitet wird, siehste nichts. Das ist so auch gut so, nur so kannst du das Bild erst fertig zeichnen (wenn es aufwändiger ist) und auf einen Schlag das fertige Bild anzeigen.
Egal, ob das jetzt stimmt oder nicht: Wenn du mir als ein paar Mikrosekunden brauchst, um ein Event abzuarbeiten, machst du was falsch. Auf diesem Thread arbeitet man nicht. Wenn es aufwändiger wird, dann starte von dort aus nen Thread, in dem du die Arbeit machst.
-
Ingmar schrieb:
Was die Threads angeht, um das zu verstehen: Würde es dann reichen die Datenverarbeitung (die das Datenmodell der Ameise und ihre Bewegung regelt) in einen eigenen Thread zu packen und diesen dann schlafen zu lassen?
So macht man das üblicherweise, yip.