Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 361
  • Last Modified:

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();
  }
}
0
sayd
Asked:
sayd
  • 10
  • 5
1 Solution
 
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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
 
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

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 10
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now