1

I need to create a class AnimatedImage that will take an array of Image objects and display them in a round robin fashion given some time interval.

The idea is to have Swing components use this AnimatedImage class the same way they use regular BufferedImage to display images. The AnimatedImage will switch actual Images in a round-robin fasion and the swing components will be notified to display the next actual image.

My problem is that I can't find a way to notify the swing component that AnimatedImage has switched the actual Image.

I hope you can understand what I mean.

Any help will be appreciated!

What I have done so far:

public class AnimatedImage extends BufferedImage
{
    private final Image[] images;

    private int imageIndex = 0;

    public AnimatedImage(Image[] images, int interval)
    {
        super(images[0].getWidth(null), images[0].getHeight(null), BufferedImage.TYPE_INT_ARGB);

        this.images = images;

        ActionListener listener = new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                iterate();
            }
        };
        Timer timer = new Timer(interval, listener);
        timer.start();
    }

    private void iterate()
    {
        imageIndex = imageIndex + 1 >= images.length ? 0 : imageIndex + 1;
    }

    public float getAccelerationPriority()
    {
        return images[imageIndex].getAccelerationPriority();
    }
    public ImageCapabilities getCapabilities(GraphicsConfiguration gc)
    {
        return images[imageIndex].getCapabilities(gc);
    }
    public Image getScaledInstance(int width, int height, int hints)
    {
        return images[imageIndex].getScaledInstance(width, height, hints);
    }
    @Override
    public Graphics getGraphics()
    {
        return images[imageIndex].getGraphics();
    }

    @Override
    public int getHeight(ImageObserver observer)
    {
        return images[imageIndex].getHeight(observer);
    }

    @Override
    public Object getProperty(String name, ImageObserver observer)
    {
        return images[imageIndex].getProperty(name, observer);
    }

    @Override
    public ImageProducer getSource()
    {
        return images[imageIndex].getSource();
    }

    @Override
    public int getWidth(ImageObserver observer)
    {
        return images[imageIndex].getWidth(observer);
    }
}
mdzh
  • 1,030
  • 2
  • 17
  • 34
  • 1
    *"How to extend BufferedImage in order to create an “animated image” that consists of multiple BufferedImages"* The JSE support for animated GIFs suggests that `BufferedImage` (& `Image` for that matter) already support animated images. See [this answer](http://stackoverflow.com/a/8549677/418556) for tips on creating the animation. – Andrew Thompson Nov 28 '13 at 14:21
  • Yes, I know that JSE support animated GIFs. The thing is that I do not want to use actual animation, but rather simulate it by switching different images in a round robin fashion. – mdzh Nov 28 '13 at 14:32
  • *"The thing is that I do not want to use actual animation.."* (shrugs) OK - I was whipping up an example, but I won't bother.. – Andrew Thompson Nov 28 '13 at 14:34
  • @AndrewThompson: if you are right, then my answer is wrong. Please look at my answer and let me know. Thanks. – Hovercraft Full Of Eels Nov 28 '13 at 15:06
  • @AndrewThompson: and If I am wrong, then you really should provide an answer that should then be accepted, if not for the OP, then for the future visitors to this site that actually do need an animation. Again, thanks! – Hovercraft Full Of Eels Nov 28 '13 at 15:14
  • `My problem is that I can't find a way to notify the swing component that AnimatedImage has switched the actual Image.` that is why the `AnimatedIcon` needs the component the Icon is being painted for. I would guess you have the same requirement here. – camickr Nov 28 '13 at 21:31

1 Answers1

2

It would seem to me that you're going about this wrong, that extending a BufferedImage would give you no tools to notify or to display the change. For my money, I'd instead create several ImageIcons and swap the Icons in a JLabel using a Swing Timer.


Edit
You state in comment:

Why not? I'm sure there is a way to notify or to display a change. Whether it would be by implementing/passing ImageObserver or something else... I have a very large infrastructure of JComponents that are heavily dependent on Image instances. I can not simply start using Icons and JLabels

Because:

  1. It seems to me that for one, your class doesn't represent a true "is-a" relationship to a BufferedImage which is a concrete image that holds a data buffer for its colors. Your attempted solution violates the Liskov substitution principle in that no matter how you structure your solution, there is no chance that your new class can be substituted for BufferedImage in other situations and have it work properly.
  2. Your attempted solution delves into making fundamental changes to low-level concepts, that of subclasses of Image, when it is almost always safer and much easier to maintain solutions that use higher-level concepts.
  3. Your question smells strongly of being an XY-problem. And sometimes it is in fact better to restructure your code.
Community
  • 1
  • 1
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • Why not? I'm sure there is a way to notify or to display a change. Whether it would be by implementing/passing ImageObserver or something else... I have a very large infrastructure of JComponents that are heavily dependent on Image instances. I can not simply start using Icons and JLabels... – mdzh Nov 28 '13 at 14:35
  • 1
    +1, @mdzh,`For my money, I'd instead create several ImageIcons and swap the Icons in a JLabel using a Swing Timer.` - For example see [Animated Icons](http://tips4java.wordpress.com/2009/06/21/animated-icon/). – camickr Nov 28 '13 at 16:24
  • @camickr, I managed to do what I wanted using this article. Instead of Icons I used Images and the Graphics2D object to draw them. I also needed to set the composite to AlphaComposite.SRC so that new images don't overlay. Thanks a lot!! – mdzh Nov 29 '13 at 11:02