Solved

Using a Timer

Posted on 2003-11-17
16
317 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
Comment Utility
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
Comment Utility
> currentImage = (++currentImage)% TOTAL_IMAGES;

Shouldn't be in your paintComponent method...

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

Expert Comment

by:TimYates
Comment Utility
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
 
LVL 35

Expert Comment

by:TimYates
Comment Utility
Actually, ignore that (the paintIcon bit)...

your way should work :-)
0
 
LVL 35

Accepted Solution

by:
TimYates earned 400 total points
Comment Utility
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
Comment Utility
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
Comment Utility
>  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
Comment Utility
Did that work?
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:sayd
Comment Utility
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
Comment Utility
THis is the only way of doing it...
0
 
LVL 35

Expert Comment

by:TimYates
Comment Utility
> 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
> 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
Comment Utility
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

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
triangle challenge 4 75
endX challenge 2 48
count11 challenge 6 47
mockito example issue 8 26
For customizing the look of your lightweight component and making it look lucid like it was made of glass. Or: how to make your component more Apple-ish ;) This tip assumes your component to be of rectangular shape and completely opaque. (COD…
By the end of 1980s, object oriented programming using languages like C++, Simula69 and ObjectPascal gained momentum. It looked like programmers finally found the perfect language. C++ successfully combined the object oriented principles of Simula w…
Viewers will learn about basic arrays, how to declare them, and how to use them. Introduction and definition: Declare an array and cover the syntax of declaring them: Initialize every index in the created array: Example/Features of a basic arr…
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.

763 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now