Hallo allerseits,
um ein bisschen mehr Durchblick zu bekommen, habe ich etwas mit repaint() experimentiert und zwei zwei Demo-Programme (Versionen) geschrieben, die Kreise auf den Bildschirm zeichnen.
In beiden Programmen wird repaint() mehrmals in einer Schleife aufgerufen.
Ein Aufruf von repaint() zieht einen Aufruf von paintComponent(...) nach sich.
Programm2:
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 auch auf dem Bildschirm: es wird nur der letzte Kreise dargestellt!
Dies ist auch klar: Der letzte Kreis ist der aktuellste.
Das ist mir auch alles noch klar.
Aber:
Programm1:
Obwohl repaint() mehrfach aufgerufen wird, wird nur der erste Kreis gezeichnet.
Aber der erste Kreis ist der unaktuellste, der veraltetste Kreis.
Frage1:
Warum wird nicht - wie bei Programm1 - der aktuellste Kreis gezeichnet?
Frage2:
Wenn man das Fenster vergrößert/verkleinert, wird repaint() aufgerufen (von der VJM)
Warum wird aber repaint() nicht (von der VJM) aufgerufen, wenn man das Fenster auf dem Bildschirm verschiebt (bewegt, nicht vergrößert oder verkleinert)?
Frage3:
Wenn man bei Programm1 statt while(k<10) schreibt while(true), bekommt man einen Compilerfehler, da dann die Anweisung f.setVisible(true); nicht mehr erreichbar wird.
Man könnte daher die repaint()-Anweisungen in einen Thread packen (in die Methode run), dann vor der Anweisung
f.setVisible(true);
diesen Thread starten.
Ist das richtig?
mfg
Ernst
----------------------------------------------------
--------------------------------------
um ein bisschen mehr Durchblick zu bekommen, habe ich etwas mit repaint() experimentiert und zwei zwei Demo-Programme (Versionen) geschrieben, die Kreise auf den Bildschirm zeichnen.
In beiden Programmen wird repaint() mehrmals in einer Schleife aufgerufen.
Ein Aufruf von repaint() zieht einen Aufruf von paintComponent(...) nach sich.
Programm2:
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 auch auf dem Bildschirm: es wird nur der letzte Kreise dargestellt!
Dies ist auch klar: Der letzte Kreis ist der aktuellste.
Das ist mir auch alles noch klar.
Aber:
Programm1:
Obwohl repaint() mehrfach aufgerufen wird, wird nur der erste Kreis gezeichnet.
Aber der erste Kreis ist der unaktuellste, der veraltetste Kreis.
Frage1:
Warum wird nicht - wie bei Programm1 - der aktuellste Kreis gezeichnet?
Frage2:
Wenn man das Fenster vergrößert/verkleinert, wird repaint() aufgerufen (von der VJM)
Warum wird aber repaint() nicht (von der VJM) aufgerufen, wenn man das Fenster auf dem Bildschirm verschiebt (bewegt, nicht vergrößert oder verkleinert)?
Frage3:
Wenn man bei Programm1 statt while(k<10) schreibt while(true), bekommt man einen Compilerfehler, da dann die Anweisung f.setVisible(true); nicht mehr erreichbar wird.
Man könnte daher die repaint()-Anweisungen in einen Thread packen (in die Methode run), dann vor der Anweisung
f.setVisible(true);
diesen Thread starten.
Ist das richtig?
mfg
Ernst
----------------------------------------------------
Code:
// Programm1
import java.awt.*;
import javax.swing.*;
public class MainTest7{
public static void main(String[] args){
int k;
k = 0;
JFrame f = new JFrame();
f.setSize(550,550);
Diagramm diagramm = new Diagramm(550, 550);
f.getContentPane().add(diagramm);
// while(true){
while(k<10){
diagramm.repaint();
k=k+1;
}
f.setVisible(true);
}
}
class Diagramm extends JPanel{
private int xpAnz;
private int ypAnz;
private int i,j;
private Image myimg;
private Graphics myg;
private int sx;
private int sy;
public Diagramm(int xpAnz, int ypAnz){
i=0;
this.xpAnz=xpAnz;
this.ypAnz=ypAnz;
myimg=null;
}
public void paintComponent(Graphics g){
if(myimg==null){
sx = this.getSize().width;
sy = this.getSize().height;
myimg = createImage(sx, sy);
myg = myimg.getGraphics();
}
myg.setColor(Color.red);
myg.drawOval(i , i, 20, 20);
i=i+20;
System.out.println("i="+i);
synchronized(myimg){
g.drawImage(myimg,0,0,null);
}
}
}
Code:
// Programm2
import java.awt.*;
import javax.swing.*;
public class MainTest8 {
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,k;
private Image myimg;
private Graphics myg;
private int sx;
private int sy;
public Diagramm(int xpAnz, int ypAnz){
i=0;
this.xpAnz=xpAnz;
this.ypAnz=ypAnz;
myimg=null;
}
public void paintComponent(Graphics g){
if(myimg==null){
sx = this.getSize().width;
sy = this.getSize().height;
myimg = createImage(sx, sy);
myg = myimg.getGraphics();
}
myg.setColor(Color.red);
myg.drawOval(i , i, 20, 20);
g.drawImage(myimg,0,0,null);
}
public void run(){
k = 0;
i=11;
// while(true){
while(k<10){
this.repaint();
try{
//Thread.sleep(500);
}
catch(Exception e){}
i = i+20;
k = k+1;
}
}
}