Hallo Leute,
Ich habe hier ein ernstahftes Problem mit ser awt.EventQueue:
Ich schreibe gerade an einem Programm, das zeigen soll, wie Linien und Kreise gerastert werden und zeichne daher sehr große "Pixel" und vor allem mit verstellbarer Geschwindigkeit.
Dies kann jedoch lästig werden, wenn man beispielsweise ein gefülltes Rechteck zeichnet und versehentlich eine sehr langsame Zeichengeschwindigkeit gewählt hat.
Daher wollte ich zumindest eine Möglichkeit schaffen, den Zeichenvorgang abzubrechen, was jedoch einen Schritt ins (wie ich schon zu spüren bekommen habe) sehr komplexe Feld des Multithreading unabdingbar macht.
Ich habe also einen Thread eingerichtet, der das Zeichnen neuer
Figuren übernimmt.
Dazu habe ich in meine Klasse "DrawingPanel" (von JPanel abgeleitet, zum Zeichnen aller Figuren bestimmt) schlicht "Runnable" implementiert.
Dort werden dann aus der "run"-Methode heraus meine (selbstgeschriebenen) Zeichenmethoden aufgerufen.
Dies scheint auch wunderbar zu funtkionieren, mit dem einen Haken, dass die Wartezeit nach dem setzen jedes Pixels (von der ja die Zeichengeschwindigkeit abhängt) völlig zu entfallen scheint und die Figur immer sofort vollständig zu sehen ist.
Nach einiger Recherche fand ich erstaunt heraus, dass mein eigens angelegter Thread den Zeichenvorgang völlig korrekt ausführt, sich aber die EventQueue einmischt und alles zunichte macht:
Mein Thread (heiße er t) beginnt völlig korrekt mit der Ausführung der Zeichenmethode, setzt auch den ersten Pixel und beginnt dann zuwarten.
Nun mischt sich nach kurzer (sehr kurzer!) Zeit die EventQueue ein und beginnt ebenfalls (in einem weiteren Thread), die Zeichenmethode auszuführen (die "run" Methode wird nicht erneut ausgeführt), verzichtet aber großzügig aufs warten und setzt die Zeichenschleife fort, wodurch die Figur sofort erscheint. :bahnhof:
t zeichnet danach zwar noch völlig korrekt die Linie weiter (mit Warten), dies hat jedoch keinen Effekt mehr, das sie ja schon zur Gänze sichtbar ist. :x
An dieser stelle ist zu erwähnen, dass ich das Warten nicht mit Thread.sleep veranlasse (diese Methode rundet die eingegebene wartezeit in millisekunden auf hundertstelsekunden, wodurch sie für meine zwecke viel zu ungenau wird), sondern mit einer Leerschleife, die nach einer bestimmten zeit in nanosekunden beendet wird.
Ich halte den Thread also bloß beschäftigt, bis er weiterzeichnen soll. (Gibt's da bessere Lösungen?)
Wenn ich die Zeichenmethode mit "synchronized" synchronisiere, führt t das Zeichnen richtig aus und ich sehe die Figur langsam entstehen, kann währenddessen aber wiederum nicht auf meine steuerelemente zugreifen (warum eigentlich?). Außerdem mischt sich auch hier wieder die EventQueue ein, die nun zwar nicht mehr meinem t dazwischenfunken kann, trotzdem aber noch seinen Senf dazugeben muss und die Linie nochmal zeichnet - wieder ohne Warten. (auch wenn mich das an dieser stelle eigentlich nicht mehr zu interessieren braucht, finde ich es sonderbar)
Wie kommt die überhaupt dazu, sich da einzumischen?! Ich hab schon versucht sie einfach auszuschalten, finde aber keine Möglichkeit und halte es auch eigentlich nicht für eine gute idee, da ich nicht genau weiß, wozu die sonst noch gut ist.
Gibt es da irgendeine elegante lösung?
Bin echt verzweifelt.
Gute Nacht und vielen Dank für jegliche Hilfe,
SuperSeppel13
Ich habe hier ein ernstahftes Problem mit ser awt.EventQueue:
Ich schreibe gerade an einem Programm, das zeigen soll, wie Linien und Kreise gerastert werden und zeichne daher sehr große "Pixel" und vor allem mit verstellbarer Geschwindigkeit.
Dies kann jedoch lästig werden, wenn man beispielsweise ein gefülltes Rechteck zeichnet und versehentlich eine sehr langsame Zeichengeschwindigkeit gewählt hat.
Daher wollte ich zumindest eine Möglichkeit schaffen, den Zeichenvorgang abzubrechen, was jedoch einen Schritt ins (wie ich schon zu spüren bekommen habe) sehr komplexe Feld des Multithreading unabdingbar macht.
Ich habe also einen Thread eingerichtet, der das Zeichnen neuer
Figuren übernimmt.
Dazu habe ich in meine Klasse "DrawingPanel" (von JPanel abgeleitet, zum Zeichnen aller Figuren bestimmt) schlicht "Runnable" implementiert.
Dort werden dann aus der "run"-Methode heraus meine (selbstgeschriebenen) Zeichenmethoden aufgerufen.
Dies scheint auch wunderbar zu funtkionieren, mit dem einen Haken, dass die Wartezeit nach dem setzen jedes Pixels (von der ja die Zeichengeschwindigkeit abhängt) völlig zu entfallen scheint und die Figur immer sofort vollständig zu sehen ist.
Nach einiger Recherche fand ich erstaunt heraus, dass mein eigens angelegter Thread den Zeichenvorgang völlig korrekt ausführt, sich aber die EventQueue einmischt und alles zunichte macht:
Mein Thread (heiße er t) beginnt völlig korrekt mit der Ausführung der Zeichenmethode, setzt auch den ersten Pixel und beginnt dann zuwarten.
Nun mischt sich nach kurzer (sehr kurzer!) Zeit die EventQueue ein und beginnt ebenfalls (in einem weiteren Thread), die Zeichenmethode auszuführen (die "run" Methode wird nicht erneut ausgeführt), verzichtet aber großzügig aufs warten und setzt die Zeichenschleife fort, wodurch die Figur sofort erscheint. :bahnhof:
t zeichnet danach zwar noch völlig korrekt die Linie weiter (mit Warten), dies hat jedoch keinen Effekt mehr, das sie ja schon zur Gänze sichtbar ist. :x
An dieser stelle ist zu erwähnen, dass ich das Warten nicht mit Thread.sleep veranlasse (diese Methode rundet die eingegebene wartezeit in millisekunden auf hundertstelsekunden, wodurch sie für meine zwecke viel zu ungenau wird), sondern mit einer Leerschleife, die nach einer bestimmten zeit in nanosekunden beendet wird.
Ich halte den Thread also bloß beschäftigt, bis er weiterzeichnen soll. (Gibt's da bessere Lösungen?)
Wenn ich die Zeichenmethode mit "synchronized" synchronisiere, führt t das Zeichnen richtig aus und ich sehe die Figur langsam entstehen, kann währenddessen aber wiederum nicht auf meine steuerelemente zugreifen (warum eigentlich?). Außerdem mischt sich auch hier wieder die EventQueue ein, die nun zwar nicht mehr meinem t dazwischenfunken kann, trotzdem aber noch seinen Senf dazugeben muss und die Linie nochmal zeichnet - wieder ohne Warten. (auch wenn mich das an dieser stelle eigentlich nicht mehr zu interessieren braucht, finde ich es sonderbar)
Wie kommt die überhaupt dazu, sich da einzumischen?! Ich hab schon versucht sie einfach auszuschalten, finde aber keine Möglichkeit und halte es auch eigentlich nicht für eine gute idee, da ich nicht genau weiß, wozu die sonst noch gut ist.
Gibt es da irgendeine elegante lösung?
Bin echt verzweifelt.
Gute Nacht und vielen Dank für jegliche Hilfe,
SuperSeppel13