AWT-Repaintvorgang führt wieder zu voller Auslastung.

Kai008

Erfahrenes Mitglied
Hatte vor ein paar Monaten das Problem schon einmal.
Damals wusste keiner eine Lösung, und habe das Projekt deshalb pausiert.
Hab jetzt wieder mal ein neues angefangen, und plötzlich wieder das selbe Problem. Meine javaw.exe lastet dem Kern auf dem sie rennt voll aus.
Eventuell findet jemand jetzt eine Lösung?


Zuerst einmal die simple Paint-Methode der Frame-Klasse:


Java:
public void paint(java.awt.Graphics g)
{
	this.paint.run(g);
}

paint ist vom Typ Paint und wird im Konstruktor der Klasse initialisiert.

Dann die Klasse Paint.java:

Java:
package core;

public class Paint
{
	private core.Main main;
	private core.MainFrame mainframe;
	
	public Paint(core.MainFrame mainframe, core.Main main)
	{
		this.main = main;
		this.mainframe = mainframe;
	}
	public void run(java.awt.Graphics g)
	{
		this.paintTerrain(g);
		this.paintPlayer(g);
	}
	private void paintTerrain(java.awt.Graphics g)
	{
		int x = 0;
		int y = 0;
		java.util.HashMap<String, Terrain> terrainmap = main.getTerrainmap();
				
		for(int i = 0; i < 16; i++)
		{
			for(int j = 0; j < 16; j++)
			{
				g.drawImage(terrainmap.get(x + "|" + y).getImage(), x * 36 + 3, y * 36 + 23, this.mainframe);
				x++;
			}
			x = 0;
			y++;
		}
	}
	private void paintPlayer(java.awt.Graphics g)
	{
		core.Player player = this.main.getPlayer();
		g.drawImage(player.getImage(), player.getPosX(), player.getPosY(), this.mainframe);
	}
}

Zuerst einmal wird ihr beim intialisieren die Klasse Main.java und MainFrame.java übergeben.
Main führt Standartarbeiten durch (z. B. lesen von Files), hält einen großen Teil der globalen Variablen und eben son Zeug.
MainFrame ist natürlich das Frame.

Und zu guter letzt ein Thread:

Java:
package core;

public class Repaint extends Thread
{
	private final int fps = 33;
	private core.MainFrame mainframe;
	
	public Repaint(core.MainFrame mainframe)
	{
		this.mainframe = mainframe;
	}
	public void run()
	{
		while(true)
		{
			try
			{
				this.mainframe.repaint();
				Thread.sleep(1000 / fps);
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
		}
	}
}

Dieser wird einfach vom Frame gestartet und sorgt für ständiges Repainten.

Findet jemand dem Fehler?
 
Schau dir mal SwingUtilities.invokeLater an. Eigentlich solltest du nicht über einen anderen Thread GUI-Methoden aufrufen. Das geht in Swing zwar (im Gegensatz zu SWT), allerdings nicht unbedingt gut.
 
Danke. Heißt dass, ich soll damit dem Aufrufethread pausieren, bis er mit dem Repaintvorgang fertig ist?
Die Idee dahinter war, dass wenn sich nichts verändert stört ihm sicher keine Repaints, und wenn sie etwas verändert kann es passieren, dass jedes von z. B. 10 Objekten ständig einen Repaintauftrag absendet, was wohl unnötig wäre.
Ich dachte mir vorhin, dass eventuell einfach eine HashMap für dem Vorgang zu langsam ist, wäre mir aber um einiges lieber, da ich bei einen ältern Projekt bei sowas immer eine ArrayList durchrennen musste, um zu prüfen ob auf dem Feld überhaupt etwas steht. Und das hat mich sehr generft. Und HashMap/ArrayList parallel fände ich auch nicht so schön.
Deshalb kam ich auf die Idee, bei der initialisierung aus dem Terrain einfach eine einzige Image-Datei erzeuge die ich dann einfach anzeige, dafür habe ich aber noch keine Informationen gefunden.

€: OK, hab jetzt folgendes versucht:

Das Terrain wurde parallel in eine Liste geladen, und mit dieser wurde angezeigt. Hat nichts verändert.
Und dann noch, dass die void paint() des Frames die generierte g-Variable in eine Klassenvariable kopiert hat, und der Thread die Zeichenfunktionen direkt als Methode drinnen.
Dann wurde die paint aufgerufen, die Klassenvariable zurückgegeben, und versucht mit dieser zu zeichnen. Hat aber nichts genutzt, da er ständig von vorne begonnen hat. :eek:
 
Zuletzt bearbeitet:
Zurück