Home > Net >  Java Swing: Spinning Image Animation
Java Swing: Spinning Image Animation

Time:12-17

I am trying to create spinning image Animation but something seems to be not working in the code. I am rotating image at various angles and drawing it but at the end I only end up single rotated image than animation. Is this possible to do in Java or do I need switch to C# Unity where I found multiple examples on doing so nothing so far in Java. I am new to Swing so I would really appreciate simplified answer.

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.util.concurrent.TimeUnit;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class Rotate extends JPanel {
    
    public static void main(String[] args) {
        new Rotate().go();
    }
    
    public void go() {
        JFrame frame = new JFrame("Rotate");
        JButton b = new JButton("click");
        
        MyDrawPanel p = new MyDrawPanel();
        frame.add(p);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(1000, 1000);
        frame.setVisible(true);
        
        for(int i = 0; i < 300; i  ) {
            try {
                TimeUnit.MILLISECONDS.sleep(50);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
            repaint();
        } 
        
    }

    class MyDrawPanel extends JPanel{
        Image image = new ImageIcon(
                getClass()
                .getResource("wheel.png"))
                .getImage();
        
        public void animateCircle(Graphics2D g2d ) {
            //g2d = (Graphics2D) g2d.create();
            g2d.rotate(Math.toRadians(25), 250, 250);
            g2d.drawImage(image, 0, 0, 500, 500, this);
        }
        
        @Override
        protected void paintComponent(Graphics g) {
            //super.paintComponent(g);
            g.fillRect(0, 0, this.getWidth(), this.getHeight());
            Graphics2D g2d = (Graphics2D) g; 
            animateCircle(g2d);
        }
    }
}

I tried moving for loop in the paintComponent() method but it didn't help either.

CodePudding user response:

Here

    public void animateCircle(Graphics2D g2d ) {
        //g2d = (Graphics2D) g2d.create();
        g2d.rotate(Math.toRadians(25), 250, 250);
        g2d.drawImage(image, 0, 0, 500, 500, this);
    }

You rotation is fixed, so you aren't seeing your image spinning

By changing your value in Math.toRadians(...), you can make it appear to spin

This

    for(int i = 0; i < 300; i  ) {
    rotationStep   ;
        try {
            TimeUnit.MILLISECONDS.sleep(50);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
        repaint();
    } 
  }

Is the wrong way to do animation in swing. The right way is to use a javax.swing.Timer

public class MyTimer implements ActionListener {
  int rotationStep = 0;
  public void actionPerformed(ActionEvent ae) {
//    for(int i = 0; i < 300; i  ) {
    rotationStep   ;
    repaint();
  }
}

CodePudding user response:

One issue with your code is that you are calling the repaint() method on the Rotate panel, but the panel you want to repaint is the MyDrawPanel panel. To fix this, you should call the repaint() method on the MyDrawPanel panel instead.

Another issue is that you are using a for loop to try to update the image rotation. However, this will only update the image once and will not create an animation. To create an animation, you need to use a timer to update the image at regular intervals.

Here is an example of how you can modify your code to create a spinning image animation:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Rotate extends JPanel {
    public static void main(String[] args) {
        new Rotate().go();
    }

    public void go() {
        JFrame frame = new JFrame("Rotate");

        MyDrawPanel p = new MyDrawPanel();
        frame.add(p);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(1000, 1000);
        frame.setVisible(true);

        // Create a timer to update the image rotation at regular intervals
        int delay = 1000 / 60; // 60 FPS
        Timer timer = new Timer(delay, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                p.angle  = 5; // Rotate by 5 degrees
                p.repaint();
            }
        });
        timer.start();
    }

    class MyDrawPanel extends JPanel {
        Image image = new ImageIcon(
                getClass()
                        .getResource("wheel.png"))
                .getImage();
        int angle = 0;

        public void animateCircle(Graphics2D g2d) {
            g2d.rotate(Math.toRadians(angle), 250, 250);
            g2d.drawImage(image, 0, 0, 500, 500, this);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            animateCircle(g2d);
        }
    }
}

This code creates a timer that fires an event every 1000 / 60 milliseconds, which corresponds to a frame rate of 60 FPS. The actionPerformed method updates the angle of rotation and repaints the panel, causing the image to spin.

I hope this helps! Let me know if you have any questions.

  • Related