How to make an image library for image buffering?

Hi!

I would like to have some mechanism for loading my images before the game actually start so I can be sure I don’t have to wait for them to load during play. I’ve writte a small ImageLibrary class that uses the DefaultToolkit to load the images and then I associate each image with its filename in a HashMap. The problem is that I can’t use a MediaTracker to track the loading of the images since its constructor demans an Component as an argument and it makes no sense to me to use one since the library doesn’t have anything to do with that part of the program.

Best Regards,

Johan Tibell

MediaTracker requires a Component; it is, however, legal to call its constructor using null as the Component.

[quote]MediaTracker requires a Component; it is, however, legal to call its constructor using null as the Component.
[/quote]
is it?

From what I can see in the src, if you construct a MediaTracker with a null, it will throw a NullPointerException the first time you try and make it load any of the images youve added to it.

these are the only mentions of the passed in Component that I can find (there are no checks for a null parameter)


    Component target;

    ..
    ..

    public MediaTracker(Component comp) {
      target = comp;
    }

    ..
    ..
    ..
    ..

    int getStatus(boolean doLoad, boolean doVerify) {
        if (doVerify) {
            int flags = tracker.target.checkImage(image, width, height, null);

    ..
    ..
    ..


    void startLoad() {
        if (tracker.target.prepareImage(image, width, height, this)) {
            setStatus(COMPLETE);
        }

As for the issue of having an image loading library, that has no direct association with the AWT architecture.
You could use toolkit.createImage(), toolkit.prepareImage, and the ImageObserver interface to manage the loading of the images yourself.

However, I must point out, the internal representation of an loaded image can be affected by where you intend to render the image.
For instance, on a multi-display system, the internal representation for the 2 [or more] display devices maybe different.
This may mean images loaded for the default device will not render correctly onto the other devices (or will render far slower, because of pixel format conversion)

This is my experience as well. I tried that approach and got the NullPointerException.

Does the ALLBITS flag in the ImageOberver interface tell you that loading is finished? It’s a bit unclear, drawing is mentioned.

I understand that, I won’t be using two displays. Do you have any other sugestions how to keep track of 30+ images of varying type (filetype and purpose) and size?

yup, ALLBITS signifies the image loading is complete.

ImageObserver can be used for both drawing and loading, its basically whenever an asynchronous transfer of pixel data occurs.

Well, currently it sounds like you’ve got a HashMap of images?

How about something like this… (its quasi-seudo-code :D)



public void startLoad()
{
   FOR ALL ELEMENTS IN THE HASHMAP
   {
      toolkit.prepareImage(imageFromHashMap,-1,-1,imgObs);
   }
}

public void waitForImages()
{
   synchronized(imgObs)
   {
      if(imgCount==SIZE OF HASHMAP) return;
      imgObs.wait();
   }
}

int imgCount = 0;

public synchronized boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height)
{
   if ((infoflags&ALLBITS)==ALLBITS)
   {
      imgCount++;
      if(imgCount==SIZE OF HASHMAP)
      {
         notifyAll();
         return false;
      }
   }
   else return true;
}

So I launch an ImageOberver as a thread and then have the main thread wait for it? Then the run method of the ImageOberver much look something like this right (pseudoish)?

public void run()
{
      while (imageCount < HashMap.Size)
      {
      }
}

I probably should have the main thread yield() also. Do I really have to do a notifyAll()?

  • Johan