Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Using a Timer

Posted on 2003-11-17
16
335 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
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 
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

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
javap not working 8 58
login jsp example 24 65
Is Applet the way to go for my drag and drop system? 8 25
Java program running SQL query 5 37
An old method to applying the Singleton pattern in your Java code is to check if a static instance, defined in the same class that needs to be instantiated once and only once, is null and then create a new instance; otherwise, the pre-existing insta…
Java functions are among the best things for programmers to work with as Java sites can be very easy to read and prepare. Java especially simplifies many processes in the coding industry as it helps integrate many forms of technology and different d…
The viewer will learn how to implement Singleton Design Pattern in Java.
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 …

860 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