ZoomImage flackert -> Fehler: repaint-Aufruf [gelöst]

Status
Nicht offen für weitere Antworten.

Dragonfire

Bekanntes Mitglied
Hihu,

Folgender Entwurf schwebt mir vor:
Ich übergebe einer Klasse, die von JPanel erbt,
eine Hintergrundbild und das zu zommende Bild in höchster Auflösung,
sowie Startpunkte (zur Vereinfachung zurzeit konstant).

Hab mir schon einiges so Double-Buffering und Zeichnen mit Swing durchgelesen ..
irgendwas mache ich aber falsch ...

Aufgrund dieses Thread hier;

http://www.java-forum.org/awt-swing-swt/80077-bilder-skaliert-zeichnen.html

habe ich mich entschieden alle Bilder erst zu rendern,
anschließend zu zoomen ...

Wenn das Bild gezommt ist und ich die Größe des Fensters minimiere oder
ein anderes davor schiebe gibt es keine Probleme ...

Beim zoomen flackert allerdings mein Bild ..
Ich dachte Swing hätte einen automatischen Buffer?
(BufferStrategy)

Wie verhindere ich ein Flackern ?

Kann ich getGraphics() in myZoom irgendwie vermeiden?

[HIGHLIGHT="Java"]public class ZoomImage3 extends JPanel
{
//DATENFELDER

private int startX;
private int startY;
private BufferedImage bakImg;
private BufferedImage zoomImg;
private ImageProducer2 imageProducer;

private int tmpWidth;
private int tmpHeight;
private int speed = Image.SCALE_REPLICATE;
private int pixel = 4;
private Image currentImage;
//for Double-Buffering
private Image[] tmpImg;
private Graphics tmpG;

public ZoomImage3(ImageProducer2 imageProducer)
{
this.imageProducer = imageProducer;
}

public void setBakImg(BufferedImage bakImg)
{
this.bakImg = bakImg;
this.tmpImg = new Image[90];
}

public void setImg(BufferedImage zoomImg)
{
setPreferredSize(new Dimension(600,600));
this.zoomImg = zoomImg;
startX = 20;
startY = 20;
tmpWidth = 10;
tmpHeight = 10;
currentImage = zoomImg.getScaledInstance(tmpWidth, tmpHeight, speed);
}

public void zoomImage()
{
myZoom();
}

/**
* modifizierte "paint"-Methode,
* zeichnet das jeweiliges Hintergrundbild und aktuelle Bild.
*/

public void paintComponent(Graphics g)
{

super.paintComponent(g);
g.drawImage(this.bakImg, 0, 0, this);
g.drawImage(this.currentImage, startX, startY, this);
}

public void myZoom()
{
tmpG = this.getGraphics();
speed = Image.SCALE_FAST;
for(int i = 0; i < tmpImg.length ; i++)
{
tmpImg = zoomImg.getScaledInstance(tmpWidth, tmpHeight, speed);
tmpHeight += pixel;
tmpWidth += pixel;
}

for(int i = 0; i < tmpImg.length; i++)
{
currentImage = tmpImg;
paintComponent(tmpG);
}
speed = Image.SCALE_AREA_AVERAGING;
paintComponent(tmpG);
}


public void updateImage(Graphics g)
{
paintComponent(g);
}
}//class close[/HIGHLIGHT]

PS.: Wie lautet der tag für die Javaformatierung hier im Forum ?
Code:
 sieht nicht so schön aus ...
 
Zuletzt bearbeitet:
Das tmpG löschst du erstmal komplett. Wenn du zeichnen möchtest, dann rufst du repaint() auf.
Was soll das updateImage und wer ruft es auf?
 
Das updateImage könnte mit dem ImageObserver zu tun haben - aber das muss man nicht selbst implementieren....
 
ES GEHT !!!
Danke an alle ..
da wäre ich nie darauf gekommen ...
Kann mir jemand ein gutes Tutorial bezüglich Graphics und Co empfehlen?
(Also paintComponent(), repaint(), doLayout(), ...)
ich meine nicht den Umgang mit JButton und so,
dass kann ich hoffentlich xD

Hier mein Prototype:

[highlight=Java]
public class ZoomImage3 extends JPanel
{
//DATENFELDER

private int startX;
private int startY;
private BufferedImage bakImg;
private BufferedImage zoomImg;
private ImageProducer2 imageProducer;

private int tmpWidth;
private int tmpHeight;
private int quality = Image.SCALE_REPLICATE;
private int speed = 12;
private int pixel = 4;
private Image currentImage;
//for Double-Buffering
private Image[] tmpImg;

public ZoomImage3(ImageProducer2 imageProducer)
{
this.imageProducer = imageProducer;
}

public void setBakImg(BufferedImage bakImg)
{
this.bakImg = bakImg;
this.tmpImg = new Image[(400 / this.pixel)-10];
}

public void setImg(BufferedImage zoomImg)
{
setPreferredSize(new Dimension(600,600));
this.zoomImg = zoomImg;
startX = 20;
startY = 20;
tmpWidth = 10;
tmpHeight = 10;
currentImage = zoomImg.getScaledInstance(tmpWidth, tmpHeight, speed);
}

public void zoomImage()
{
myZoom();
}

/**
* modifizierte "paint"-Methode,
* zeichnet das jeweiliges Hintergrundbild und aktuelle Bild.
*/

public void paintComponent(Graphics g)
{

super.paintComponent(g);
g.drawImage(this.bakImg, 0, 0, this);
g.drawImage(this.currentImage, startX, startY, this);
}

public void myZoom()
{
//rendering of the resizes images
for(int i = 0; i < tmpImg.length; i++)
{
tmpImg = zoomImg.getScaledInstance(tmpWidth, tmpHeight, quality);
tmpHeight += pixel;
tmpWidth += pixel;
}

//repaint
for(int i = 0; i < tmpImg.length; i++)
{
currentImage = tmpImg;
repaint();
try
{
Thread.sleep(speed * speed / (i+1) );
}
catch(Exception e)
{
System.out.println("Thread interrupted: ZoomImage @" + e);
}
}
repaint();
}
}//class close
[/highlight]


Nachtrag:

updateImage kam wie von "Marco13" richtig vermutet aus ImageObserver
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben