Reputation: 5
I have four images that I am cycling between to create a simple animation. Each image is a frame of a repeating animation and I have a timer change the image to the next frame to make it animated. Every time I change the image there is a flicker where the window is all white in between displaying the next image. How do I remove this flicker?
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Reveal extends JFrame
{
private JPanel panel = new JPanel(); //a panel to house the label
private JLabel label = new JLabel(); //a label to house the image
private String[] image = {"Jack in the Box 1.png","Jack in the Box 2.png","Jack in the Box 3.png","Jack in the Box 4.png","Jack in the Box 5.png","Jack in the Box 6.png","Jack in the Box 7.png"}; //an array to hold the frames of the animation
private ImageIcon[] icon = new ImageIcon[7]; //an array of icons to be the images
private Timer timer;
private Timer timer2;
int x = 0;
int y = 4;
int counter = 0;
/**
* Constructor for objects of class Reveal
*/
public Reveal()
{
for (int h = 0; h < 7; h++){
icon[h] = new ImageIcon(image[h]);
icon[h].getImage().flush();
label.setIcon(icon[h]);
}
//Display a title.
setTitle("Raffel");
//Specify an action for the close button.
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Sets the size of the window
setSize(800,850);
panel = new JPanel();
label = new JLabel();
panel.add(label);
add(panel);
setVisible(true);
}
public void display(String name, int number){
timer = new Timer(150, new ActionListener(){
public void actionPerformed(ActionEvent e) {
if (counter > 48){
timer.stop();
timer2.start(); //starts the second half of the animation
}else{
label.setIcon( icon[x] );
if (x != 3){
x++;
}else{
x = 0;
}
counter++;
} //ends if-else
} //ends action method
}); //ends timer
timer2 = new Timer(150, new ActionListener(){
public void actionPerformed(ActionEvent e) {
if (y > 6) {
timer2.stop();
}else{
label.setIcon( icon[y] );
y++;
} //ends if-else
} //ends action method
}); //ends timer2
timer.start();
}
}
Upvotes: 0
Views: 269
Reputation: 324098
icon[x] = new ImageIcon(image[x]);
icon[x].getImage().flush();
label.setIcon( icon[x] );
I would suggest that you don't keep reading the images from disk.
Load all the ImageIcons into an array at the start of your class and then just cycle through the array to get the next Icon to update the label.
Edit:
The animation has only 4 unique frames.
But you have an array of 7 icons.
icon[h].getImage().flush();
There is no need for the flush. You are just creating ImageIcons.
label.setIcon(icon[h]);
Why do you keep setting the icon of the label each time you create a new Icon? This means the last Icon created will be the first Icon displayed.
I would expect you should assign icon[0] to the label AFTER the loop is finished. I would guess this is the cause of the flicker because the last icon is briefly displayed before the first. So if you default to the first you won't have a problem.
The animation has only 4 unique frames. The animations is 64 frames long playing each image as a frame 16 times
You don't need 2 Timers for this. You need two variables.
Upvotes: 2