I'm trying to make a flip effect with java swing, but my flip method doesn't look like a real flip.In my method I change the width with the x var and the xspeed, making the image smaller and then check if the x is >= as half of my image. hope somebody could help me improve it thanks in advance.
Animation Class
public class Animation extends JPanel implements MouseListener {
private static final long serialVersionUID = 3264508834913061718L;
public Timer timer;
public int x = 0;
public int xspeed = 2;
public boolean turning = true;
public String pic = "/images/image.jpg";
public URL url = this.getClass().getResource(pic);
public ImageIcon im = new ImageIcon(url);
public String rev = "/images/image2.jpg";
public URL url2 = this.getClass().getResource(rev);
public ImageIcon reverse = new ImageIcon(url2);
public Animation(){
this.setPreferredSize(new Dimension(128,128));
this.setBackground(Color.BLACK);
this.setFocusable(true);
this.addMouseListener(this);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(im.getImage(), 0 , 0, im.getIconWidth() - x, im.getIconHeight(), null);
}
public void flipAnimation(){
ActionListener actionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
//
if (turning) {
x = x + xspeed;
}
repaint();
// x in the middle paint new image & set turning to false to stop animation
if(x >= im.getIconWidth()/2){
turning = false;
x = 0;
im = reverse;
}
}
};
if (turning) {
if (timer != null)timer.stop();
timer = new Timer(30, actionListener);
timer.start();
}
}
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
e.getSource();
flipAnimation();
}
First, I’m guessing you want your image to “fold in” from both sides, so you’ll want to increase the image’s left edge along with its right edge:
g.drawImage(im.getImage(), x / 2 , 0, im.getIconWidth() - x, im.getIconHeight(), this);
Notice the first int argument has been changed from 0
to x / 2
. Also, it is good practice to pass this
as the ImageObserver argument when drawing images in a paintComponent method, since the component itself is the object which is interested in repainting itself when the image has finished loading in the background.
Second, change this:
if (turning) {
x = x + xspeed;
}
to this:
x = x + xspeed;
You don’t need a flag to control the animation. (The correct way to stop the animation is to call timer.stop(), which I’ll get to in a moment.)
Third, change this:
if(x >= im.getIconWidth()/2){
turning = false;
x = 0;
to this:
if(x >= im.getIconWidth()){
xspeed = -xspeed;
turning
flag is not needed.x
to the image’s width, instead of half of the width, is that we want to change the image only when the first image has completely “folded in.”xspeed
reverses the animation.Finally, at the end of your actionPerformed method, you’ll want to add this:
if (x <= 0) {
timer.stop();
}
This halts the animation when the reverse image reaches its full size, which is why the turning
flag is not needed.