Probleme mit repaint()

Status
Nicht offen für weitere Antworten.
Hallo,
ich habe folgendes Problem.
Bei einer Demonstrationsanwendung, bei der auf dem Bildschirm dargestellt werden soll,
wie ein bestimmter geometrischer Algorithmus funktioniert- es werden häufig irgendwelche Linien verschoben, wird mein Panel trotz repaint()- Anweisung nicht regelmäßig neugezeichnet.
Wenn ich mein Programm debugge, funktioniert alles einwandfrei.
Es ist auch nicht so, dass mein Programm zum Zeitpunkt des Neuzeichnens stark mit irgendwelchen Rechnungen belastet wäre. Im Gegenteil, ich lasse den Haupthread unmittelbar nach einem repaint etwas schlafen, damit man sich das neue Bild in Ruhe anschauen kann. Es wäre also alle Zeit der Welt für einen repaint vorhanden.
Hat jemand eine Idee, woran es liegen könnte.
Es ist mir klar, das zur Beantwortung der Frage eine compilierfähige Version meins Programms sinnvoll wäre. Es ist aber schwierig, den entsprechenden Teil herauszulösen. Vielleicht hat jemand einen allgemeinen Hinweis, woran es liegen könnte. Da beim Debuggen alles problemlos funktioniert, weiß ich im Moment nämlich nicht so recht weiter, wie ich den Fehler finden soll.
Viele Grüße
winterwanderer
 
winterwanderer hat gesagt.:
Es ist auch nicht so, dass mein Programm zum Zeitpunkt des Neuzeichnens stark mit irgendwelchen Rechnungen belastet wäre. Im Gegenteil, ich lasse den Haupthread unmittelbar nach einem repaint etwas schlafen, damit man sich das neue Bild in Ruhe anschauen kann. Es wäre also alle Zeit der Welt für einen repaint vorhanden.

Das ist Quatsch. Mach es richtig: http://java.sun.com/docs/books/tutorial/uiswing/painting/

Für Quereinsteiger: http://java.sun.com/docs/books/tutorial/uiswing/painting/problems.html

Zum Verständnis:http://java.sun.com/docs/books/tutorial/uiswing/painting/closer.html
 
falls es erlaubt ist, zu fragen, ohne 10 Seiten zu lesen:
was ist daran Quatsch?
 
SlaterB hat gesagt.:
was ist daran Quatsch?
Wenn etwas nicht gezeichnet wird ist der Hintergrund in der Regel der, dass Swing nicht richtig verwendet wird. Wenn man diesen Link kennt (http://java.sun.com/products/jfc/tsc/articles/painting/ bzw. den anderen Links folgt sieht man wie man das richtig macht und wieso.

Diese Posting fühlt sich wie die falsche Verwendung von Swing an (evtl. custom painting aus dem eigenen Thread), mehr lässt sich mit diesen Informationen nicht sagen.

Was ist Quatsch: der sleep(), denn das ist keine Garantie, dass etwas gezeichnet wurde.
 
Hallo,
mit den Lessons zum Zeichnen habe ich mich durchaus schon beschäftigt (auch wenn ich nicht behaupten will, dass ich deswegen alles richtig mache.) Mein Problem ist dadurch aber nicht gelöst. Dass ich meinen Thread, der meine Demonstration durchführt, schlafen lege, hat aber durchaus seine Berechtigung. Wie gesagt, ich möchte einen Algorithmus visualisieren. Damit der Beobachter jeden Schritt in Ruhe anschauen kann, muss ich sowieso Pausen einbauen. Warum wird in diesen Pausen nicht gezeichnet? Das repaint() verläuft doch, so wie ich es verstehe, in einem eigenen Thread und wird dann durchgeführt, wenn Kapazitäten zum Zeichnen vorhanden sind. Wenn das Programm ansonsten nichts tut, warum zeichnet es dann nicht ?
Und warum klappt es beim Debuggen?
Zur Veranschaulichung werd ich jetzt doch noch etwas Code posten.
Also zuerst meine Methode, in der repaint () aufgerufen wird.


Code:
private void zeichneKanten(int index, int xPos, int yPos){
		PolygonPunktZeichner poPZ = polygonzugZeichner.get(index);
		poPZ.setNachKantenColor(Color.GREEN);
		zeichenPanel.repaint();
		try {
			Thread.sleep(1000);
		} 
		catch (InterruptedException e){}
		if ((aakt==amaxsolong)){
			KantenZeichner kZ;
			kZ = new KantenZeichner(poPZ.getX0(), poPZ.getY0(),poPZ.getXNach(),poPZ.getYNach(),zeichenPanel);
			kZ.setObereKante(poPZ.getX0()>poPZ.getXNach());
			kZ.setKantenColor(Color.GREEN);
			kZ.setTransportLinie(true);
			zeichenPanel.repaint();		
			try {
				Thread.sleep(1000);
			} 
			catch (InterruptedException e){}
			kZ.bewegeKante(xPos, yPos);
			zeichenPanel.repaint();
			poPZ.setNachKantenColor(Color.RED);
		}
		else
			poPZ.setNachKantenColor(Color.BLACK);
	}

Nun meine paintComponent-Methode
Code:
	protected void paintComponent(Graphics g){
			super.paintComponent(g);
			for (IDrawable componente : zeichenKomponenten)
				componente.draw(g);
			}

Für eine konstruktive Antwort wäre ich dankbar.











Code:
Code:
Code:
Code:
 
FArt hat gesagt.:
Was ist Quatsch: der sleep(), denn das ist keine Garantie, dass etwas gezeichnet wurde.
aber ist das denn auch kontroproduktiv?

allgemein scheint es mir nicht abwegig, dass ein Programm, welches ständig 100% CPU-Last hat,
seltener oder mit zumindest minimaler Verzögerung zum Zeichnen kommt

-------

> Also zuerst meine Methode, in der repaint () aufgerufen wird.

wichtig ist noch, wer diese Methode aufruft, ein Thread (dann: wer startet den wann wie wo) oder wer anders?
 
Hallo SlaterB,
Ok, ich will versuchen, die Programmstruktur mal etwas darzustellen.
Ich habe eine Klasse 'Hauptmenucontroller implements ActionListener', die in ihrer actionPerformed - Methode
einen Thread startet, der meine Demonstration durchführt.
Innerhalb dieses Threads wird dann die Klasse 'KantenauswahlDemo' erzeugt.
Die Methode 'zeichneKanten(int index, int xPos, int yPos)' ist eine Methode dieser Klasse.
Sie wird aus einer anderen Methode dieser Klasse heraus aufgerufen.


Das Seltsame ist folgendes: Das Programm tut eigentlich alles, was es soll. Der Algorithmus wird korrekt umgesetzt und irgendwann wird auch alles auf einmal gezeichnet, was aber eben schrittweise gezeichnet werden sollte.
Ab diesem Zeitpunkt läuft das Programm korrekt weiter. Das heißt, nun zeichnet es auch auf einmal, die einzelnen Zeichnungen Schritt für Schritt, wie es gedacht ist. Nur funktioniert dies eben nicht von Anfang an, sondern erst nach einer gewissen Zeit. Aus irgendeinem Grund lässt sich das Programm also anfangs nicht auf das repaint() ein, später aber dann doch. Dieses Verhalten erscheint mir sehr wunderlich.
 
Ich würde das über die SwingUtilities versuchen. Wenn du auf die Ausführung warten musst, dann wäre invokeAndWait evtl. in Kombination mit einer künstlichen Verzögerung besser.
 
Hallo, danke für eure Antworten.
Ich habe den Fehler nun gefunden.
Ich habe in einer update-Methode eine Schlafpause eingebaut. Bei von mir selbst aufgerufenen updates war das o.k. Ich wollte, dass danach stets dass Bild etwas eingefroren stehen bleibt.
Nun gab es aber auch vom System verursachte updates, die in einem eigenen Thread abliefen.... 😳
Meine eingebaute Pause wirkte sich hier so aus, dass das restliche Programm normal weiterlief. Das Neuzeichnen hier aber verzögert wurde. Das Neuzeichnen wurde dann erst veranlasst, nachdem mehrere System.updates zusammenkamen und das Programm mal Zeit hatte, diese zu zeichnen.
Dieses Problem konntet ihr von außen natürlich nicht lösen. Ich bin erst darauf gestoßen, indem ich überal Zeitmarken einrichtete und so erkannte, wo Zeit verbraten wurde.
Tut mir Leid.
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben