Hallo allerseits,
um mehrfach hintereinander z.B. Kreise auf dem Bildschirm auszugeben, genügt es nicht, in einer Schleife immer wieder repaint aufzurufen.
Grund:
Jeder Aufruf von repaint() sorgt nur dafür, dass ein paint in die EDT-Warteschlange (EventDispatcher-Thread = Thread, der die graphische Oberfläche zeichnet und Events herumschickt) gestellt wird.
Ein durch einen alten repaint-Aufruf in die EDT-Warteschlange gestelltes paint wird durch ein neueres (durch einen neuen repaint-Aufruf) in die EDT-Warteschlange gestelltes paint
ersetzt (ein paint() zieht ein paintComponent(...) nach sich). Man sagt dazu auch "coalescing" (verschmelzen, vereinigen). Mehrere Aufrufe werden zu einem vereinigt.
Das sieht man z.B. auch auf dem Bildschirm: es wird nur der letzte Kreise dargestellt, weil er der aktuellste ist.
So weit ist mir das alles noch verständlich.
"kleiner Held" hat mir dankenswerterweise (unten) ein Programm vorgestellt, mit dem man das Problem lösen kann. Dieses Programm benutzt "synchronized", mit dem verhindert werden soll, dass mehrere Threads gleichzeitig auf die Variable myimg zugreifen können.
Frage:
In der EDT-Warteschlange befinden sich (durch mehrere repaint() Aufrufe verursachte) paint (ein paint() zieht ein paintComponent(...) nach sich)) Aufrufe (wobei einige durch "coalescing" vereinigt wurden).
kurz:
paint1()
paint2()
paint3()
....
Das Wort "Warteschlange" in EDT-Warteschlange bedeutet doch, dass die einzelnen paint() _hintereineinander_ ausgeführt werden müssen, aber dann braucht man doch _kein_ synchronized, da dies dann nicht nebenläufig, also _nicht_ parallel erfolgt (und es dann keine Probleme beim Zugriff verschiedener, parallel laufender Threads auf _eine_ Variable gibt).
Oder wo ist da mein Denkfehler?
mfg
Ernst
um mehrfach hintereinander z.B. Kreise auf dem Bildschirm auszugeben, genügt es nicht, in einer Schleife immer wieder repaint aufzurufen.
Grund:
Jeder Aufruf von repaint() sorgt nur dafür, dass ein paint in die EDT-Warteschlange (EventDispatcher-Thread = Thread, der die graphische Oberfläche zeichnet und Events herumschickt) gestellt wird.
Ein durch einen alten repaint-Aufruf in die EDT-Warteschlange gestelltes paint wird durch ein neueres (durch einen neuen repaint-Aufruf) in die EDT-Warteschlange gestelltes paint
ersetzt (ein paint() zieht ein paintComponent(...) nach sich). Man sagt dazu auch "coalescing" (verschmelzen, vereinigen). Mehrere Aufrufe werden zu einem vereinigt.
Das sieht man z.B. auch auf dem Bildschirm: es wird nur der letzte Kreise dargestellt, weil er der aktuellste ist.
So weit ist mir das alles noch verständlich.
"kleiner Held" hat mir dankenswerterweise (unten) ein Programm vorgestellt, mit dem man das Problem lösen kann. Dieses Programm benutzt "synchronized", mit dem verhindert werden soll, dass mehrere Threads gleichzeitig auf die Variable myimg zugreifen können.
Frage:
In der EDT-Warteschlange befinden sich (durch mehrere repaint() Aufrufe verursachte) paint (ein paint() zieht ein paintComponent(...) nach sich)) Aufrufe (wobei einige durch "coalescing" vereinigt wurden).
kurz:
paint1()
paint2()
paint3()
....
Das Wort "Warteschlange" in EDT-Warteschlange bedeutet doch, dass die einzelnen paint() _hintereineinander_ ausgeführt werden müssen, aber dann braucht man doch _kein_ synchronized, da dies dann nicht nebenläufig, also _nicht_ parallel erfolgt (und es dann keine Probleme beim Zugriff verschiedener, parallel laufender Threads auf _eine_ Variable gibt).
Oder wo ist da mein Denkfehler?
mfg
Ernst
Code:
package de;
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class MainVerzoegertZeichnen4 {
public static void main(String[] args){
JFrame f = new JFrame();
f.setSize(550,550);
Diagramm diagramm = new Diagramm(550, 550);
f.getContentPane().add(diagramm);
Thread t = new Thread(diagramm);
t.start();
f.setVisible(true);
}
}
class Diagramm extends JPanel implements Runnable{
private int xpAnz;
private int ypAnz;
private int i;
private Image myimg;
public Diagramm(int xpAnz, int ypAnz){
i=0;
this.xpAnz=xpAnz;
this.ypAnz=ypAnz;
myimg = new BufferedImage(xpAnz, ypAnz, BufferedImage.TYPE_INT_RGB);
}
//@Override
/*
public Dimension getPreferredSize()
{
return new Dimension(xpAnz, ypAnz);
}
*/
protected void paintComponent(Graphics g){
synchronized(myimg){
g.drawImage(myimg,0,0,null);
}
}
public void addKreis(){
synchronized(myimg){
Graphics myg = myimg.getGraphics();
myg.setColor(Color.red);
myg.drawOval(i , 2*i+15, 20, 20);
myg.dispose();
}
}
public void run(){
// while(i<200){
while(true){
try{
//Thread.sleep(500);
}
catch(Exception e){
}
i = i+20;
addKreis();
this.repaint();
}
}
}