# Im JLabel Bild durch anderes ersetzen, ohne dass es 'blinkt'



## Jank90 (14. Mrz 2008)

Hi an alle,

in meinem Programm wird ein Bild angezeigt, welches nach einer bestimmten Zeit durch ein anderes ersetzt wird. Das Bild zeige ich momenten in einem JLabel an und ändere es durch:
label.setIcon();
Dadurch entsteht aber manchmal so ein hässlicher blink Effekt. Ich denke das kommt daher, dass das alte Icon erst entfernt wird und dann ein neues hineingezeichnet wird. Zwichendrin ist das Label also kurz leer und daher sieht es dann aus als ob es blinken würde.
Ich habe auch versucht zwei Label zu machen, die direkt übereinander liegen und unterschiedliche Bilder enthalten. Eins ist unsichtbar. Nach einer Zeit habe ich dieses dann sichtbar gemacht und das vorher sichtbare unsichtbar, aber es trat wieder der gleiche Effekt auf.
Es wär echt super, wenn mir jemand sagen könnte, wie ich es anstellen kann, das die Bilder ohne blinken wechseln.

Zur Erläuterung: Auf den Bildern ist ein Kreis abgebildet. Auf dem einen etwas größer als auf dem anderen. Der Hintergrund ist gleich, sodass der Kreis eigentlich nur größer werden sollte.

Beispielcode:

```
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JFrame
{
	public static void main(String[] args) {
		JFrame frame = new JFrame();
		JLabel bild1 = new JLabel(),
			  bild2 = new JLabel(),
		          sec   = new JLabel();
		ImageIcon a = new ImageIcon("a.gif"),
				b = new ImageIcon("b.gif");
		
		frame.setTitle("Gif Test");
		frame.setSize(400,400);
		frame.setLocation(376,232);
		frame.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent evt) { System.exit(0); }
		});
		Container cp = frame.getContentPane();
		cp.setLayout(null);
		bild1.setBounds(0,0,400,200);
		bild1.setIcon(a);
		bild1.setVisible(true);
		bild2.setBounds(0,0,400,200);
		bild2.setIcon(b);
		bild2.setVisible(false);
		sec.setBounds(0,200,400,200);
		sec.setText("Bild wechselt in...");
		
		cp.add(bild1);
		cp.add(bild2);
		cp.add(sec);
		frame.setVisible(true);
		
		try
        {
			for(int i=3;i>=0;i--)
			{
				Thread.sleep(1000);
				sec.setText(sec.getText()+" "+i);
			}
			// Erste Möglichkeit
			bild1.setIcon(b);
			// Zweite Möglichkeit
			//bild2.setVisible(true);
			//bild1.setVisible(false);
        }
        catch (InterruptedException e)
        {
          System.err.println(e);
        }
	}
}
```

Vielen Dank schon mal

Jan


----------



## zilti (14. Mrz 2008)

Du musst das Label noch doubleBuffered setzen. Ich glaub setDoubleBuffered(true)


----------



## Jank90 (17. Mrz 2008)

Hi,
tut mir Leid, dass ich erst so spät antworte. Hatte am Wochenende keine Zeit.
Erstmal danke für den Tip. Bringt aber glaube ich nichts. Dieses kurze blinken tritt immernoch auf.

Mir ist aufgefallen, dass das blinken nicht immer auftritt, wenn ich zwei Label habe und mit setVisible arbeite. Allerdings kommt es auch so ab und zu vor. Kann es sein das man das vielleicht gar nicht ändern kann, wenn man zwei Bilder "austauscht"?

Mir ist da auch noch eine Möglichkeit eingefallen. Ist es möglich eine gif-Animation erst an einem bestimmten Zeitpunkt im Programm zu starten, und nicht sofort, wenn Sie geladen wird?

Jan


----------



## MiDniGG (17. Mrz 2008)

Hey,

habs mal nachgebaut und bei isses so, wenn ich bsp en Bild 250x250 hab und des in nen frame mit 300x300 reintu schauts gut aus. wenn ich des bild aba in en 500x500 frame pack dann flackert es und das Bild rutscht sogar rum. Deshalb mein Tipp. Kein Null-Layout!!! ;-)

Aba kein Plan obs daran liegt...


----------



## Quaxli (17. Mrz 2008)

Es könnte auch an dem animierten GIF liegen, wenn Du so etwas verwendest. Meiner Erfahrung nach, kann es gut gehen, animierte GIF's zu verwenden, aber auch problematisch sein. Auf der sicheren Seite bist Du, wenn Du Animationen mit Einzelbildern selbst erstellst.


----------



## MiDniGG (17. Mrz 2008)

Naja... Da er einen kleinen Kreis groß machen will denk ich ma nicht, dass das animiert ist...

Habs etz nochmal 1:1 mit deinem getestet (was vorhin ned ging weil ich keine / bei den Bildern hatte...   ) und also bei mir flackert da gar nix... Egal mit welcher Methode... Kann vllt auch noch am Arbeitsspeicher liegen... oder sowas in die Richtung...

*Edit:* So und jetzt hab ich s noch mit nem seeehr großen gif (Transparent) getestet und da flackert au nix. Schöner fließender Übergang 

*Edit2:* OK. Jetzt kommt der Abschuss............Hab jetzt 2 animierte GIFs aus m Net genommen die sogar noch transparent sind........Ergebnis: Perfekt. Kein Flackern beim Wechsel....

Also ich weiß ned was du hast ;-)


----------



## Jank90 (17. Mrz 2008)

Ja, also ich muss sagen, bei mir merk ich auch nix mehr. Aber ich hab am Code nichts verändert und an den Bildern auch net.

Das ist jetzt seltsam. Vielleicht liegts wirklich am Arbeitsspeicher. Und wenn ichs jetzt so oft teste sind die Bilder schon geladen.

Naja. Auf jeden Fall hat sich das jetzt erledigt.

Danke für die Hilfe.


----------



## Jank90 (17. Mrz 2008)

Weiß vielleicht jemand, wie ich die Bilder schon vor dem Anzeigen in den Arbeitsspeicher laden kann?
Das ist doch bestimmt möglich, oder?


----------



## MiDniGG (17. Mrz 2008)

Ich denk mal, wenn die Bild mit nem Puffer lädst sollte es dein Zeil erfüllen.

Also irgendwie BufferedImage eben nur dann musst dein JLabel auch ändern, dass dann eben ein Bild geladen wird kein Icon mehr...


----------



## Jank90 (17. Mrz 2008)

Gute Idee. Aber ich glaube mit BufferedImages kann man keine Gif-Animationen anzeigen, oder? Ich kriege es zumindest nicht hin.


----------



## MiDniGG (17. Mrz 2008)

Ui... Du stellst Fragen...  Musste ma googeln... Hab ich echt kein Plan...


----------



## MiDniGG (17. Mrz 2008)

Vllt hilft das ja...

http://mathsrv.ku-eichstaett.de/MGF/homes/grothmann/java/kurs/Images.html


----------



## Jank90 (7. Apr 2008)

Falls das jetzt noch jemanden interessiert:

Ich habe das Problem folgendermaßen gelöst. Ich habe die Gifs als Image geladen und das Ganze mit dem MediaTracker und der Funktion waitForAll() überwacht.
Dann habe ich eine Klasse mit veränderter paintComponent() von JPanel abgeleitet.
Auf dieses JPanel habe ich die Bilder das mittels der veränderten paintComponent() gezeichnet.

Funktioniert einwandfrei. Die Gifs bewegen sich noch und es entsteht kein Flackern beim Bilderwechsel.

Jan


----------

