# Bild zu zeichnen (drawImage) klappt nur manchmal??



## Novanic (9. Nov 2006)

Hi Leute,

ich habe ein merkwürdiges Problem. Auf diesem JPanel sollen Bilder gezeichnet werden. Das klappt auch, aber leider nicht bei jedem Starten des Programms.

Die Komponente wird aber richtig in meine GUI geadded (das kann ich an der Hintergrundfarbe sehen), aber das Startbild dass auf dem JPanel gezeichnet werden soll, ist nicht immer zu sehen. Auch das erzwingen des Repaints nützt in dem Fall nichts (Fenstergröße ändern, play() ausführen, ...).

Ich kann z.B. 5 mal das Programm über die IDE starten und alles läuft so wie gewünscht. Beim 6. Start wird plötzlich kein Image mehr angezeigt, dann starte ich es wieder und dann gehts wieder...
(Zwischen den Starts habe ich nichts am Code geändert und zwischen den Starts beende ich das Programm jedesmal wieder und an der IDE und fehlenden Image-Dateien kann es auch nicht liegen).

Hat jemand eine Idee wodran dieser Mythos liegen kann?

Danke schonmal im Voraus! 

Gruß Nova



```
package game.real.engine.animation;

import game.real.engine.animation.render.Render;

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

public class AnimationRender extends JPanel implements Render
{
    private static final boolean DIRECTION_FORWARD = true;
    private static final boolean DIRECTION_BACKWARD = false;

    private Animation myAnimation;
    private int myCurrent;
    private int myPauseTime;
    private Thread myRunner;
    private boolean myDirection;

    public AnimationRender()
    {
        myCurrent = 0;
        myPauseTime = 35;
    }

    public void play()
    {
        play(DIRECTION_FORWARD);
    }

    public void playback()
    {
        play(DIRECTION_BACKWARD);
    }

    private void play(boolean aDirection)
    {
        if(myDirection != aDirection)
        {
            myDirection = aDirection;
            stop();
        }

        if(myRunner == null)
        {
            myRunner = new Thread(this);
            myRunner.start();
        }
    }

    public void stop()
    {
        if(myRunner != null)
        {
            myRunner = null;
        }
    }

    public void paint(Graphics aScreen)
    {
        super.paint(aScreen);
        Graphics2D theScreen = (Graphics2D)aScreen;
        if(myAnimation != null) {
            Image[] theImages = myAnimation.getImages();
            theScreen.drawImage(theImages[myCurrent], 0, 0, this);
        }
    }
    
    public void run()
    {
        if(myAnimation != null) {
            Thread theCurrentThread = Thread.currentThread();
            if(myDirection)
            {
                while(myRunner == theCurrentThread)
                {
                    myCurrent++;
                    int theImageCount = myAnimation.size();
                    if(myCurrent >= theImageCount)
                    {
                        myCurrent = myCurrent - 1;
                        stop();
                    }
                    repaint();
                    try {
                        Thread.sleep(myPauseTime);
                    } catch(InterruptedException e) { /*do nothing*/ }
                }
            } else {
                while(myRunner == theCurrentThread)
                {
                    myCurrent--;
                    if(myCurrent < 0)
                    {
                        myCurrent = myCurrent + 1;
                        stop();
                    }
                    repaint();
                    try {
                        Thread.sleep(myPauseTime);
                    } catch(InterruptedException e) { /*do nothing*/ }
                }
            }
        }
    }

    public Animation getAnimation()
    {
        return myAnimation;
    }

    public void setAnimation(Animation aAnimation)
    {
        myAnimation = aAnimation;
    }
}
```


----------



## SlaterB (9. Nov 2006)

das Laden eines Images ist nicht ganz trivial,
das kann schon mal ne Weile dauern,

vielleicht wartet dein Programm nicht, bis das Bild fertig geladen ist,
poste den Code für das Laden der Bilder

und du bist dir sicher, dass myAnimation nicht null ist?
kann man mit einem einfachen System.out.println() prüfen..


----------



## Novanic (9. Nov 2006)

Hi,

also myAnimations ist nicht NULL, das hatte ich schon mit einem System.out geprüft.
Die Images werden vorher geladen, die müssten doch gecached sein oder?

Die Images werden geladen und in einem Animation-Objekt gehalten. Das Animation-Objekt wird dann an den AnimationRender ^^ übergeben.


```
File[] theVariationImages = aVariation.listFiles(theFileFilter);

Image[] theImages = new Image[theVariationImages.length];

for(int i = 0; i < theVariationImages.length; i++)
{
   try {
      Image theImage = ImageLoader.getInstance().loadImage(theVariationImages[i].getAbsolutePath());
      theImages[i] = theImage;
   } catch (IOException e) {
      throw new LoadingException();
   }
}
return new AnimationSkeleton(theImages);
```

Gruß Nova


----------



## SlaterB (9. Nov 2006)

die Klasse ImageLoader ist mir gänzlich unbekannt,
ist das etwa eine eigene Klasse von dir?

dann hast du die wahre Bedeutung des Satzes
> poste den Code für das Laden der Bilder 
nicht erfasst


----------



## Novanic (9. Nov 2006)

Hi,

die Klasse ImageLoader ist nicht von mir. Die ist im Standard-JDK und im Package "com.sun.deploy.ui". Auf die Klasse bin ich eher durch zufall gestoßen und die hatte auch funktioniert... 

Was ist denn üblich um Bilder in Image-Objekte zu laden? Am Besten so dass sie gecached sind.

Gruß Nova


----------



## SlaterB (9. Nov 2006)

siehe z.B. hier
http://www.java-forum.org/de/viewtopic.php?t=38732

der letzte Post zu ImageIcon scheint mir das sicherste


----------



## Novanic (9. Nov 2006)

Okay hab ich jetzt mal so umgebaut, das Problem besteht aber leider trotzdem noch. :-(

Bei jedem x-ten Start wird kein Image angezeigt... :-(

Gruß Nova


----------



## SlaterB (9. Nov 2006)

du könntest immer noch mal deinen Code posten und so vielleicht doch einen Fehler entdecken lassen,
aber ich fische natürlich nur im Trüben, genaue Tipps habe ich persönlich nicht,

günstig, wäre dein Programm insgesamt auf 30 Zeilen zu kürzen,
nur das eine Image in der JFrame-Klasse laden und anzeigen,
alles andere raus,

wenn das immer noch manchmal nicht geht, dann kann man das besser auf anderen Rechnern ausprobieren,

wenn es dann immer klappt:
Schritt für Schritt alles rausgeschmissene wieder einbauen und testen testen testen ;(


----------



## Novanic (9. Nov 2006)

Ah, jetzt hab ichs gefunden.

Ich hatte mich schon gewundert, warum das Problem erst nach dem Einschecken in SVN auftrat. Mein FlieFilter zum Laden der Images hatte nicht ganz richtig funktioniert und dadurch Versucht den SVN-Ordner zu laden, was ein leeres Image-Array zur Folge hatte.
Da die Animationen in einen Container gepackt werden und eine Animation per Zufall gelesen wird, konnte es vorkommen, dass das leere Image-Array erwischt wird.

Man sowas dusseliges, dass mit dem Zufallsprinzip hatte ich garnicht mehr auf dem Zettel. *g* 

Danke für die Hilfe! 

Gruß Nova


----------

