getGraphics verursacht endlosschleife
-
Hallo,
Ich habe folgendes Problem:Ich verwende einen JFrame und möchte etwas darauf zeichnen. Also rufe ich die getGraphics-Methode des JFrames auf. An dieser Stelle bleibt das Programm dann aber einfach stehen, es kommt auch keine Exception.
import java.awt.*; import javax.swing.*; import java.util.Timer.*; public class Main { public static void main(final String[] args) { JFrame window = new JFrame(); window.setTitle("adsfasdfa"); window.setResizable(false); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.setSize(800, 600); window.setVisible(true); int fps = 40; boolean end = false; while(!end) { long time = System.currentTimeMillis(); //Hier bleibt es stehen Graphics g = window.getGraphics(); g.drawLine(20,20,500,500); while(System.currentTimeMillis()<time+1000/fps); } System.exit(0); } }
Ich verwende Ubuntu Linux
Ich hoffe mir kann da jemand weiterhelfen.....Danke im Voraus
-
while(System.currentTimeMillis()<time+1000/fps);
in dieser schleife bleibt er so lange drin bis die long variable von currentTimeMills ihren wertebereich ueberschreitet und wieder bei -MAX_LONG landet
sagen wir du holst dir time bei ner systemzeit von ka... 500.000 MS und dann hast du diese 2 lines of code in 10 ms erledigt dann ist deine while schleife
while(500.000 + x < ~12.500);
und bis long von currentMills 2^32 (long hat 64 bit und ist signed glaub ich) das wieder erreicht dauert das im schnitt schon ein, zwei monate
-
nein das glaube ich nicht
Nehmen wir an die Variable time hat einen wert von 5000. Dann zähle ich zu diesem wert 1000/40 ms also 25ms dazu. Dann warte ich bis die aktuelle zeit größer wird als die 5025 ms. Diese Anweisung funktioniert schon..... das Problem liegt aber ganz wo anders, denn bis zu dieser while schleife kommt es im programmablauf gar nicht (siehe code)
System.out.println("Wird angezeigt"); Graphics g = window.getGraphics(); System.out.println("Wird nie erreicht");
aber danke für deine schnelle antwort
-
ah.. ja du hast recht
naja getGraphics sollte nicht blockieren jedenfalls, in der API steht es gibt entweder die graphics instanz zurück oder null wenn auf dem component nicht gerendert werden kann
unter windows funktioniert der code von oben 1:1 also liegt es vllt an ner fehlerhaften jvm die du unter ubuntu installiert hast?
-
ich habe jetz noch eine andere Version von Java ausprobiert .... es funktioniert aber trotzdem nicht ..... Anscheinend ist das wirklich ein Problem mit Linux......
-
ich weiss nicht, denke nicht dass es direkt mit linux zu tun hat
ich hab unter ubuntu vor nen paar wochen angefangen ein wenig java grafik zu programmieren zum rumprobieren (zwar nicht primitives sondern images - aber das prob liegt bei dir ja schon am getgraphics) und es ging alles
zwar wirft er unter ubuntu komischerweise einmal eine exception die er unter windows nicht wirft aber ich hab mir das nicht naeher angeschaut
ich werd morgen mal das codestueck mit meinem ubúntu laufen lassen und dann sag ich dir ob dasselbe passiert
bzw was du probieren koenntest auch ist anstatt direkt von dem frame ueber getContentPane().getGraphics dir die graphics instanz zu holen oder ein panel auf den frame adden und von dem dann die graphics instanz holen
-
Danke für deine Antwort.
Ich habe beide Varianten ausprobiert und er weigert sich immer noch mir eine Graphics Instanz zurückzugeben....Wenn mein Code auf deinem Linux-Rechner auch nicht funktioniert, könntest du dann vielleicht den Code für ein einfaches Grafik-Programm, das bei dir funktioniert hier rein kopieren
-
abc2 schrieb:
und möchte etwas darauf zeichnen. Also rufe ich die getGraphics-Methode des JFrames auf
Das allein ist schon fehlerhaft.
Nur in extrem extravaganten Situationen solltest du die getGraphics()-Methode
selbst aufrufen.Alle deine Zeichenoperationen sollten in der überschriebenen Methode
paintComponent(Graphics g) ausgeführt werden.
-
funktionieren sollte es aber trotzdem.... Unter windows funktioniert es ja auch
-
jo, geht auch bei mir unter unbuntu ganz normal so
vevusio@vevusio:~$ java -version java version "1.7.0" IcedTea Runtime Environment (build 1.7.0-b21) IcedTea 64-Bit Server VM (build 1.7.0-b21, mixed mode)
dass man getgraphics nicht manuell aufrufen soll, mag sein, aber es kommt immer noch auf die situation an, wenn man beispielsweise ein java game programmieren will wo man eh jeden frame immer neu zeichnet sobald es geht auch wenn sich vllt nichts verändert hat
-
ich würde dir empfehlen mal zu debuggen, damit du genau siehst an welcher stelle sich deine anwendung aufhängt. ist zwar mühselig, liefert aber doch oft hilfreiche informationen.
den aufruf von getGraphics() mit anschließendem zeichnen hab ich auf diese weise auch schon oft benutzt (windows) und das ging immer problemlos.
edit:
wenn man ein game programmieren will würde ich empfehlen dafür eine grafik API zu verwenden, die bit-blitting und page flipping beherrscht. dann musst du nicht getGraphics aufrufen und das zeichnen geht schneller (= flackerfrei).
ich weis leider nicht auswendig, ob java von haus aus so eine API hat (noch nicht benutzt unter java), würde aber drauf wetten.
hab mal gegoogelt: vielleicht hilft dir das hier http://informatik.unibas.ch/lehre/ws05/cs101/folien/18_GameCh02_A.pdfedit2:
hab mir deinen code nochmal näher angeschaut und ich hab den eindruck, dass du wirklich ein game schreiben willst. wenn das stimmt, dann (sei mir nicht böse) bist du auf diese weise wirklich auf dem holzweg. ich weis ja nicht, wie komplex dein spiel werden soll, aber spielgrafik zeichnet man eher hardware nah. man verwendet zwar ein fenster, um mit dem system kommunizieren zu können, jedoch verwendet man nicht die eigentliche zeichenmethode dessen, da diese für ein spiel mit kontinuierlicher bildwiederholrate !!viel zu langsam!! und unflexibel ist. stattdessen hat man einen main loop, in dem das bild ständig neu gezeichnet wird und dadurch dass man den inhalt des bildspeichers verändert (bit-blit) wird dann auch das bild verändert.
http://java.sun.com/docs/books/tutorial/extra/fullscreen/doublebuf.html
-
Hallo jule37
Ja du hast Recht. Das ganze war ein altes Schulprojekt dass ich ausgegraben habe. Es war war oder ist auch schon ziemlich fortgeschritten. Ich wollte das ganze dann eben auch auf linux ausprobieren und bin auf dieses Problem gestoßen. Den Code den ins Forum gestellt habe, ist eine sehr reduzierte Variante des echten Codes und soll nur das Problem veranschaulichen. Aber danke für deine Tipps!