Using a Timer

OK my timer doesnt seem to be working correctly, can some1 help pls? what i am trying to do is display a series of gif/jpg image in a jpanel, and display each for a given amount of time.

Each image only needs to be displayed once.and then the object can stop on the last image. Please let me know if there are any other errors in the code.

Eventually i would like to incorporate this object as part of a larger program by creating an instance of this object in that program. I would like to somehow halt that program while this object is running thru its images.


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

public class displayImages extends JPanel
                        implements ActionListener {
    //Set up animation parameters.

  private ImageIcon images[];
  private int currentImage = 0;
  private Timer animationTimer;
  private static final int ANIM_DELAY = 250;
  private static final int  TOTAL_IMAGES= 12;

  public displayImages() {
    this.images = new ImageIcon[TOTAL_IMAGES];
    this.setSize(this.getPreferredSize());
    for (int i = 0; i < images.length; i++){
      images[i] = new ImageIcon("Image"+i+".gif");
    }
    this.setVisible(true);
    startAnimation();
  }

  public void paintComponent(Graphics g){
    System.out.println("paint "+currentImage);
    super.paintComponent(g);
    if (images[currentImage].getImageLoadStatus() == MediaTracker.COMPLETE){
      images[currentImage].paintIcon(this,g,0,0);
      currentImage = (++currentImage)% TOTAL_IMAGES;
    }
  }

  public void startAnimation() {
    if (animationTimer == null){
      System.out.println("Timer = null");
      currentImage = 0;
      animationTimer = new Timer(ANIM_DELAY, this);
      animationTimer.start();
    }else{
      if (!animationTimer.isRunning())
        animationTimer.restart();
        System.out.println("Timer = running");
    }
  }

  public void actionPerformed (ActionEvent e) {  repaint();  }
  public void stopAnimation(){ animationTimer.stop(); }
  public Dimension getMinimumSize(){ return getPreferredSize();}
  public Dimension getPreferredSize() { return new Dimension(80,80);}

  public static void main(String[] Args){
    DiscardDemo Demo1 = new DiscardDemo();
    JFrame main = new JFrame("Discard Tiles!!");
    main.getContentPane().add(Demo1, BorderLayout.CENTER);
    main.addWindowListener(new WindowAdapter(){
      public void windowClosing(WindowEvent e){
        System.exit(0);
      }
    });
    main.pack();
    main.show();
  }
}
saydAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

saydAuthor Commented:
My bad the last bit should read....

public static void main(String[] Args){
    displayImages Demo1 = new displayImages();
    JFrame main = new JFrame("Discard Tiles!!");
    main.getContentPane().add(Demo1, BorderLayout.CENTER);
    main.addWindowListener(new WindowAdapter(){
      public void windowClosing(WindowEvent e){
        System.exit(0);
      }
    });
    main.pack();
    main.show();
  }
0
TimYatesCommented:
> currentImage = (++currentImage)% TOTAL_IMAGES;

Shouldn't be in your paintComponent method...

it should be in your actionPerformed...
0
TimYatesCommented:
If this doesn't help, maybe letting us know what the problem is would help?

----------

Also:

images[currentImage].paintIcon(this,g,0,0);

should be:

g.drawImage( images[currentImage].getImage(), 0, 0, this ) ;
0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

TimYatesCommented:
Actually, ignore that (the paintIcon bit)...

your way should work :-)
0
TimYatesCommented:
public void paintComponent(Graphics g){
    System.out.println("paint "+currentImage);
    super.paintComponent(g);
    if (images[currentImage].getImageLoadStatus() == MediaTracker.COMPLETE){
      images[currentImage].paintIcon(this,g,0,0);
    }
  }

------------

public void actionPerformed (ActionEvent e) {  
    if( currentImage == TOTAL_IMAGES - 1 )
      stopAnimation() ;
    else
    {
      currentImage ++ ;
      repaint();  
    }
}
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
saydAuthor Commented:
ok the images are now being displayed for the correct amount of time but it seems to be calling the paintComponent method as many times as it can during that time. Also when it gets to the last image it keeps calling the paintComponent for an infinite amount of time.

Can you also advise on how i get the images to be displayed the same size (shrink/enlarge to fit a given area) if the images are originally of different sizes.
0
TimYatesCommented:
>  ok the images are now being displayed for the correct amount of time

Cool :-)

> but it seems to be calling the paintComponent method as many times as it can during that time.

Hmmmm....paintComponent is called whenever the Component (in this case the JPanel) needs repainting...

This is either because you called repaint() or some other window covered up the JPanel, so it needs to redraw itself...

Works fine on my machine....

Are you resizing the window?  Moving the window?  Etc?

> Can you also advise on how i get the images to be displayed the same size (shrink/enlarge to fit a given area) if the images are originally of different sizes.

g.drawImage( images[ currentImage ].getImage().getScaledInstance( 200, 200, Image.SCALE_SMOOTH ), 0, 0, this ) ;
0
TimYatesCommented:
Did that work?
0
saydAuthor Commented:
ok so i cant stop it from calling paintComponent, but doesn't this take up computer resources.

When i add it to my main program will it keep calling this method or is there a way i could have a default image displayed without having to keep calling this method.
0
TimYatesCommented:
THis is the only way of doing it...
0
TimYatesCommented:
> but doesn't this take up computer resources.

It will call it anyway, whether you override it or not...

You could try;

 public void paintComponent(Graphics g){
    super.paintComponent( g ) ;

    System.out.println("paint "+currentImage);
    super.paintComponent(g);
    if (images[currentImage].getImageLoadStatus() == MediaTracker.COMPLETE){
      images[currentImage].paintIcon(this,g,0,0);
    }
  }

To see if it is different/better, but it should make no difference...

Tim
0
saydAuthor Commented:
the only difference i see in the above code is that you've added the line super.paintComponent( g ) ; what difference will this make?
0
TimYatesCommented:
Just means the JPanel draws itself before you do your image stuff...

There is nothing in your code that should be causing any sort of paintComponent "overload"  As I said, it works fine on my machine, and I think all you are seeing is the usual amount of calls paintComponent recieves...

Nothing to worry about....  It works fine on my machine...

Hope that getScaledInstance thing worked ok for you too...

Tim
0
saydAuthor Commented:
ive left that scaled bit out for the moment, nearly there now.

any ideas on how i could halt the main prog while this object runs thru its images.

i am calling the startAnimation() method from my main prog when an event is triggered.
0
TimYatesCommented:
> any ideas on how i could halt the main prog while this object runs thru its images.

Hmmmm....not easily :-(

0
DanninCommented:
tim just wondering if u slow down the loading(timer) will it be smother by actually sleeping the thread for a few milliseconds?
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.