# Problem mit Bilder laden mit sum.kern



## Amatsukami (30. Mrz 2011)

Guten Tag,

Ich habe ein Problem, welches etwas kompliziert zu erklären ist. Für die Schule programmieren wir momentan ein kleines Java Programm mit der Bibliothek sum.kern. Mein Problem ist, dass ich zu diesem Zweck ein Bild in das Spiel laden möchte. Der Code für genau dieses ist ja einfach und den habe ich auch, mein Problem ist jedoch, dass, aus welchem Grund auch immer, erst beim zweiten aufrufen des Dienstes ich das Bild zu Gesicht bekomme. Ich sehe also beim ersten Aufruf des Dienstes nur den weißen Bildschirm , beim zweiten jedoch nach einer verschwindend geringen Zeit das Bild.

Hier ist mal mein Code:


```
import java.awt.*;
import sum.kern.*;


public class ImageTester
{
    // Objekte
    Bildschirm b;
    
    Image test;

    // Konstruktor
    public ImageTester()
    {
        //Bildschirm initialisieren
        b = new Bildschirm(600,600);
        //Bild laden (klappt auch ganz sicher)
        test= Toolkit.getDefaultToolkit().getImage("test.gif");
    }

    // Dienste
    public void bildMalen()
    {
       //Den Bildschirm nach vorne holen
       b.nachVorn();
       //Das Bild malen
       b.getGraphics().drawImage(test, 10,30, null);
    }
}
```

Ich benutze die Entwicklungsumgebung BlueJ, und das Bild ist hier zu finden (nur ein Test): Testbild

Ich würde mich über Rückmeldung sehr freuen.

Mit freundlichen Grüßen,

Ein Gast


----------



## AmunRa (31. Mrz 2011)

Versuch mal 
	
	
	
	





```
Toolkit.getDefaultToolkit().createImage("test.gif");
```

und sonst kann dir hier mit so wenig Code niemand Helfen. Wobie mit BlueJ kenn ich mich überhaupt nicht aus daher ...


----------



## Gastredner (31. Mrz 2011)

Oder vielleicht mal mit ImageIO statt [c]Toolkit[/c] probieren.


----------



## Quaxli (31. Mrz 2011)

Zusätzlich wäre die Klasse Bildschirm noch interessant.


----------



## Amatsukami (31. Mrz 2011)

Ich probiere das heute mal aus zuhause. Und übrigens , dass ist der gesamte Code! Dies ist ja nur ein Testprogramm, was nur Bilder lädt, nicht mehr und nicht weniger.

Ich sag dann mal später Bescheid ob es geklappt hat.


----------



## noobadix (31. Mrz 2011)

Das Bild hast du mit dem Erstellen eines Image-Objektes noch nicht geladen. Dies geschieht erst beim Zeichnen durch Graphics.drawImage(...) oder mit Toolkit.prepareImage(...). ImageObserver ist von Component abgeleitet, du solltest also die Cmponent, in der das Image gezeichnet wird, als ImageObserver übergeben, der sollte nich null sein (bei drawImage(..) ).Siehe: Einbinden von Bildern


----------



## Amatsukami (4. Apr 2011)

so hat sich erledigt. getDefaultTollkit braucht einfach eine Zeit zum laden des Bildes. Beim Aufruf von bildMalen() wars einfach noch nicht geladen -.-*, also malte er ein leeres Bild.


----------



## noobadix (4. Apr 2011)

Na und wie hast du es jetzt gelöst? Der ImageObserver soll ja eben solche Fehler vermeiden, bei dir ist er aber in der methode 
bildMalen() 'null'


```
b.getGraphics().drawImage(test, 10,30, null);
```

Also wie gesagt: Anstatt 'null' gehört da die Component rein, in der gezeichnet wird!


----------



## Amatsukami (5. Apr 2011)

Ich habe es gelöst, in dem ich das ganze in einen Dienst verpackt habe, welcher die Bilder lädt.

Dieser erstellt erst ein leeres Bild und überschreibt dieses dann wieder mit dem Bild aus der Datei.

Der Code stammt zu Teilen aus der Feder meines Lehrers.


```
public BufferedImage ladeBild(String path_and_name)
    {
        //erstell ein leeres image       
        BufferedImage image = null;
        //versuch, das Bild zu laden
       try
       {
            image = ImageIO.read(new File(path_and_name));
       }
       catch( IOException ioe)
       {
            System.out.println("Bild konnte nicht geladen werden!");   
        }
       return image;
    }
```

So lädt das Bild mit dem Pfad, aufrufen tue ich das mit

```
String i= "test.gif";
pic = ladeBild(i);
```

Und dann male ich das ganze mit:


```
b.getGraphics().drawImage(pic,x,y,null);
```

Ich sehe nicht wirklich Sinn darin <null> durch den Componen zu ersetzen, auf den ich male, da es in diesem Miniprogramm auch so klappt.


Danke für die Hilfe an alle.


----------



## noobadix (5. Apr 2011)

Der Zweck des ImageObservers ist der, den Ladeprozess eines zu zeichnenden Bildes zu überwachen. Denn wie du festgestellt hast, ist dieser Prozess fehleranfällig.

Es ist so, dass das Bild erst beim Aufruf der Methode drawImage(...) in den Arbeitsspeicher geladen wird und das Laden kann ein zeitaufwendiger Prozess sein. Woher soll die JVM wissen, wann das Laden des Bildes geschehen ist? Durch den ImageObserver und darum ist er so wichtig.

Die Methode Graphics.drawImage(Image img, int x, int y, ImageObserver imgObs) verlangt ausdrücklich einen solchen ImageObserver und die Methode mit null abzuspeisen ist unsauber und unsicher.
Der ImageObserver "steckt" in jeder Component, also kann jede Component als ImageObserver übergeben werden.


----------

