Solved

Using a Timer

Posted on 2003-11-17
16
339 Views
Last Modified: 2010-05-18
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
Comment
Question by:sayd
  • 10
  • 5
16 Comments
 

Author Comment

by:sayd
ID: 9762963
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
 
LVL 35

Expert Comment

by:TimYates
ID: 9762971
> currentImage = (++currentImage)% TOTAL_IMAGES;

Shouldn't be in your paintComponent method...

it should be in your actionPerformed...
0
 
LVL 35

Expert Comment

by:TimYates
ID: 9762979
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
Industry Leaders: 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!

 
LVL 35

Expert Comment

by:TimYates
ID: 9762981
Actually, ignore that (the paintIcon bit)...

your way should work :-)
0
 
LVL 35

Accepted Solution

by:
TimYates earned 400 total points
ID: 9762987
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
 

Author Comment

by:sayd
ID: 9763048
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
 
LVL 35

Expert Comment

by:TimYates
ID: 9763092
>  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
 
LVL 35

Expert Comment

by:TimYates
ID: 9763258
Did that work?
0
 

Author Comment

by:sayd
ID: 9763270
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
 
LVL 35

Expert Comment

by:TimYates
ID: 9763304
THis is the only way of doing it...
0
 
LVL 35

Expert Comment

by:TimYates
ID: 9763313
> 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
 

Author Comment

by:sayd
ID: 9763371
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
 
LVL 35

Expert Comment

by:TimYates
ID: 9763386
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
 

Author Comment

by:sayd
ID: 9763475
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
 
LVL 35

Expert Comment

by:TimYates
ID: 9763583
> any ideas on how i could halt the main prog while this object runs thru its images.

Hmmmm....not easily :-(

0
 
LVL 2

Expert Comment

by:Dannin
ID: 9764517
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!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Configure a Bean in an XML file 4 48
add projects t working set in maven 2 37
Java syntax, or is it Selenium 6 37
Netbeans and org.apache.commons.lang3 issue 3 22
Java Flight Recorder and Java Mission Control together create a complete tool chain to continuously collect low level and detailed runtime information enabling after-the-fact incident analysis. Java Flight Recorder is a profiling and event collectio…
Introduction This article is the first of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article explains our test automation goals. Then rationale is given for the tools we use to a…
Video by: Michael
Viewers learn about how to reduce the potential repetitiveness of coding in main by developing methods to perform specific tasks for their program. Additionally, objects are introduced for the purpose of learning how to call methods in Java. Define …
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …

713 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question