Verzögerung bei der ersten Anzeige

fsicher

Bekanntes Mitglied
Ich zeichne in einem JFrame mehrfach eine Komponente jeweils neu und zeige sie an. Bei der ersten Anzeige ist eine Verzögerung wahrnehmbar, während die restlichen blitzschnell funktionieren. Die Anzeige ist konsistent und korrekt.

Ich habe am Ende der Methode, die das ganze steuert, ein 'beep' eingefügt. Beim ersten Durchlauf kommt das akustische Signal früher: erst danach (ca. 1 sek.) kommt das Bild. Bei wiederholten Anzeige (es wird jedes Mal neu gezeichnet), kommt das Bild vor dem akustischen Signal.

Woran könnte dies liegen?
 
Kannst du irgendwie überprüfen ob der awt thread noch reaktiv ist? Klingt nach einem hängenden Thread, was machst du denn so beim/vorm zeichnen?
 
Hört sich für mich viel mehr nach "das Bild braucht ein wenig zum laden"-problem an. Danach ists in ieinem Feld gespeichert und kann schnell abgerufen werden. Aber Ohne Code und Informationen zum Bild* lässt sich das schwer beurteilen.

* Größe in MB, Abmessungen, wird es skaliert?

MFG

Tomate_Salat
 
Etwas Code anzeigen ist nicht so einfach: es handelt sich um ca. 20 Klassen. Und Bilder sind kein Problem: wenn ich nur den Teil, in dem keine Bilder benötigt werden, ausführen lassen, ist die Verzögerung weiterhin da.

Kannst du irgendwie überprüfen ob der awt thread noch reaktiv ist? Klingt nach einem hängenden Thread, was machst du denn so beim/vorm zeichnen?

Nun, wie kann man dies prüfen?

Das Zeichnen wird direkt von einem MenuItem veranlasst, zuvor herscht Ruhe. Nach dem Zeichnen passiert nichts mehr: denn, weitere Aktionen sollen durch Menü hervorgerufen werden. Also, es ist nicht so, dass irgendetwas vor oder nach dem Zeichnen Ressourcen verbraucht. Ich habe eher den Eindruck, dass die Verarbietung von GUI-Events im Hintergrund sehr lange geht. Aber wieso nur beim ersten Mal ...

Folgendes Beispiel zeigt, wie ich es ungefähr mache:

Java:
public void refresh() {
	if (SwingUtilities.isEventDispatchThread()) {
		paintTheView();
	} else {

		SwingUtilities.invokeLater(new Runnable() {

			@Override
			public void run() {
				paintTheView();
			}
		});
	}
}

Und, in der Methode paintTheView wird (vereinfach gesagt) so etwas wie eine Tabelle (mehrere Zeilen und mehrere Spalten) gezeichnet: kleinere Quadraten, die unterschiedliche Hintergrundfarben haben.

Danke.
 
Zuletzt bearbeitet:
Nach einigen Versuchen konnte ich die Codezeile finden, die dazu führt, dass die erste Anzeige mit einer Verzögerung erfolgt. Es handelt sich um die Codezeile, in der einem JLabel-Objekt ein neues Font-Objekt zugewiesen wird (ich muss die Schriftgrösse wegen Platzmangel reduzieren).

Java:
Font newFont = new Font("Helvetica", Font.PLAIN, 10);

// ... 

for (int i = 0; i < n; i++){

// ... 

JLabel idLabel = new JLabel();

/* Folgende Zeile ist kritisch bzw. sehr teuer */
idLabel.setFont(newFont);	

// ...		
}

Diese Codezeile befindet sich in einer Schleife, die höchstens 6 Mal ausgeführt wird. Wenn ich diese Zeile auskommentiere, funktioniert es einwandfrei.

Ich habe Messungen mit System.nanoTime wiederholt gemacht (wohl wissend, dass die Genauigkeit nicht hoch ist) und konnte auch feststellen, dass im ersten Durchgang die Abarbeitung der kritischen Codezeile mehrfach (3 bis 6 Mal) länger dauert. Nach dem ersten Durchlauf bleibt die Zeit, die für die Abarbeitung dieser Codezeile benötigt wird, relativ konstant.

Weiss jemand, wieso diese Zuweisung so lange dauert? Und, gebe es eine bessere Lösung?

Danke für jeden Tipp.
 
Code:
JComponent#setFont(Font)
führt ein Repaint aus wenn Font nicht schon vorher gesetzt war (in deinem Fall also sehr wahrscheinlich). Das könnte zu der Verzögerung führen. Für Details siehe
Code:
JComponent#setFont(Font)
 

Zurück
Oben