AWT begrenzte anzahl paint aufrufe

kaetzacoatl

Bekanntes Mitglied
Hallo,
ich habe einen Thread, der repaint aufruft und
dann darauf wartet, das ein Canvas neu gezeichnet wird.
Code(gekürzt):
Java:
public class GameUpdater extends Thread implements KeyListener, MouseListener, MouseMotionListener {

	private static final long MINTIME = 20;
	private Game game;
	public ArrayList<GameObject> objs;
	private ArrayList<KeyEvent> keys;
//weitere felder

	public GameUpdater(Game game) {
		super("GameUpdater");
		this.game = game;
		objs = new ArrayList<GameObject>();
		keys = new ArrayList<KeyEvent>();
	}

//info-methoden

	@Override
	public void run(){
		long time;
		while(true){
			time = System.currentTimeMillis();			
			for(int i = 0;i < objs.size();i++){
				objs.get(i).update(this);
			}
			game.points.clear();
			for(int i = 0;i < objs.size();i++){
				game.points.addAll(objs.get(i).img);
			}
			game.repaint();
			waitForRepaint();
			System.out.println(time + " / " + (System.currentTimeMillis() - time));
			while(time + MINTIME > System.currentTimeMillis());
		}
	}

	private void waitForRepaint() {
		synchronized(game){
			try {
				game.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
//interface-methoden

}
public class Game extends Canvas {

	private static final long serialVersionUID = 5734742867859616972L;
	
	Vector<ColorPoint> points = new Vector<ColorPoint>();
	
	public Game(){
		super();
		GameUpdater gu = new GameUpdater(this);
		this.addKeyListener(gu);
		this.addMouseListener(gu);
		this.addMouseMotionListener(gu);
		gu.start();
	}
	
	@Override
	public void paint(Graphics g){
		for(int i = 0;i < points.size();i++){
			ColorPoint cp = points.get(i);
			drawPoint(g,cp.getColor(),cp.x,cp.y);
		}
		synchronized(this){
			notify();
		}
	}
	
	private void drawPoint(Graphics g, Color c, int x, int y){
		g.setColor(c);
		g.drawRect(x, y, 1, 1);
	}

}

Nach einiger Zeit gibt es allerdings keine Ausgabe
mehr und der Thread wartet auf ein notify().
1.Warum?
2.Was kann ich dagegen tun?
 
Zuletzt bearbeitet:
Du wartest darauf bis fertig gezeichnet wurde? Warum? Es gibt überhaupt keinen Grund das zu tun. Das zeichnen beeinflusst in keiner Weise die Logik des Programmes normalerweise, und wenn sie das macht, dann hat man ein falsches System aufgestellt.
Während die Logik weiterhin ausgeführt wird, kann neugezeichnet werden, deine Methode verlangsamt nur das Programm.(?)

Gruß
Net
 
Ich hab jetzt was gefunden:
Java:
@Override
	public void run(){
		long time;
		while(true){
			time = System.currentTimeMillis();			
			for(int i = 0;i < objs.size();i++){
				objs.get(i).update(this);
			}
			//game.points.clear();
			for(int i = 0;i < objs.size();i++){
				game.points.addAll(objs.get(i).img);
			}
			game.points.add(null);
			game.repaint();
			//waitForRepaint();
			System.out.println(time + " / " + (System.currentTimeMillis() - time));
			while(time + MINTIME > System.currentTimeMillis());
		}
//und
@Override
	public void paint(Graphics g){
		ColorPoint cp;
		while(!points.isEmpty() && (cp = points.remove(0)) != null){
			drawPoint(g,cp.getColor(),cp.x,cp.y);
		}
//		for(int i = 0;i < points.size();i++){
//			ColorPoint cp = points.get(i);
//			drawPoint(g,cp.getColor(),cp.x,cp.y);
//		}
//		synchronized(this){
//			notify();
//		}
	}

Ich befürchte jetzt aber,
dass Game nichtmehr mit dem
zeichnen nachkommt, daher strebe
ich immernoch eine Lösung für
mein altes Problem an.
[EDIT]
Meine Befürchtung war berechtigt,
der Vector quillt über!
[/EDIT]
 
Zuletzt bearbeitet:
Wie wäre es wenn du eine boolean-Variable einsetzt, die vor dem Aufruf repaint() auf false gesetzt wird und sobald die paint-MEthode das Ende erreicht hat setzt sie die Variable auf true.
Währenddessen wird in der Run-Methode alle paar Millisekunden abgefragt ob bereits die Variable bereits true ist.
Java:
while( !continue ) Thread.wait( 10 );

Offensichtlich geht es bei dir darum eine Liste mit Punkten zu zeichnen. Wie wäre es wenn du bei jedem durchlauf einen neuen Vector erstellst als den alten weiterhin zu verwenden?
Du verwendest eine Variable für den Vector wie du es jetzt machst, kurz vor dem zeichnen passiert aber das:
Java:
zuZeichnen = points;
points = new Vector()<ColorPoint>;
repaint();

Gruß
Net
 
Ich hab die Änderungen vom
letzten Post wieder zurückgenommen
und jetzt funktioniert alles wunderbar.
Warum:???:L
Aber trotzdem Danke für die Vorscläge.
Ich probier sie mal aus und teste obs
besser geht.
 
Statt da irgendwas per Hand zu kopieren und/oder umzuschalten kann man auch
List<Think> things = new CopyOnWriteArrayList<Thing>();
verwenden, allerdings sollte man sich im Klaren sein, dass es bei "vielen" Objekten ineffizient sein kann, wenn immer kopiert wird. (Eine einfache Lösung gibt es aber nur in Fällen, die so einfach sind, dass einen die Lösung da auch nicht mehr interessiert 😀)
 

Neue Themen


Zurück
Oben