3

I have developed a little Swing application in which i have added a Square into my JFrame using a separate class component. Now i want to rotate this Square at its center, but I am only seeing a static Square which is not rotating at all.

This is my code...

public class Rotation extends JFrame {

    Rotation() {
        super("Animation of rotation about center");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400,400);

        add(new component());

        setVisible(true);
    }

    public static void main(String args[]){
        SwingUtilities.invokeLater(new Runnable(){public void run(){new Rotation();}});
    }
}

class component extends JPanel implements ActionListener {
    Timer timer;
    Rectangle.Double r=new Rectangle.Double(100,100,50,50);
    int theta=0;

    component() {
        timer=new Timer(10,this);
        timer.start();
    }

    public void actionPerformed(ActionEvent e) {
        if (theta==360){
            theta=0;
            theta++;
        }
        repaint();
    }

    public void paint(Graphics g){
        Graphics2D g2=(Graphics2D)g;
        g2.setColor(Color.GRAY);
        g2.rotate(theta);
        g2.fill(r);
    }
}

Could someone please help me identify and fix the problem.

4

4 に答える 4

5

There is a lot of mistakes in your code:

  1. theta should be double and should be presented in radians, NOT degrees. So make it double:

    private double theta = 0;
    
  2. You do not change theta value in timer action - do that in actionPerformed:

    public void actionPerformed ( ActionEvent e )
    {
        theta += Math.PI / 18;
        if ( theta >= Math.PI * 2 )
        {
            theta = 0;
        }
        repaint ();
    }
    
  3. You do not specify the point around which the graphics context should be rotated. Do it (otherwise your square will be rotated around the beggining of coordinates (0;0)):

    public void paintComponent ( Graphics g )
    {
        super.paintComponent ( g );
    
        Graphics2D g2 = ( Graphics2D ) g;
        g2.setRenderingHint ( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
        g2.rotate ( theta, 125, 125 );
        g2.setColor ( Color.GRAY );
        g2.fill ( r );
    }
    
  4. You override component's paint method instead of paintComponent. Always use paintComponent instead as it is optimized for repaints and other Swing stuff i don't really want to talk about here because its a big offtopic.

  5. You use JPanel as a base component to paint a simple shape - use JComponent instead since you don't really need any JPanel's features (and there aren't any actually).

See the final working example:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * @see http://stackoverflow.com/a/13051142/909085
 */

public class RotationTest extends JFrame
{
    public RotationTest ()
    {
        super ( "Animation of rotation about center" );
        setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );
        setSize ( 400, 400 );

        add ( new MyComponent () );

        setVisible ( true );
    }

    public static void main ( String args[] )
    {
        SwingUtilities.invokeLater ( new Runnable ()
        {
            public void run ()
            {
                new RotationTest ();
            }
        } );
    }

    private class MyComponent extends JComponent implements ActionListener
    {
        private Timer timer;
        private Rectangle.Double r = new Rectangle.Double ( 100, 100, 50, 50 );
        private double theta = 0;

        public MyComponent ()
        {
            super ();
            timer = new Timer ( 1000 / 24, this );
            timer.start ();
        }

        public void actionPerformed ( ActionEvent e )
        {
            theta += Math.PI / 18;
            if ( theta >= Math.PI * 2 )
            {
                theta = 0;
            }
            repaint ();
        }

        public void paintComponent ( Graphics g )
        {
            super.paintComponent ( g );

            Graphics2D g2 = ( Graphics2D ) g;
            g2.setRenderingHint ( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
            g2.rotate ( theta, 125, 125 );
            g2.setColor ( Color.GRAY );
            g2.fill ( r );
        }
    }
}

As you can see i also added a rendering hint into paint method to make square movement smooth and refactored some of your code.

于 2012-10-24T14:18:15.480 に答える
3

Where the theta variable is changed?

于 2012-10-24T14:06:34.493 に答える
1
public void actionPerformed(ActionEvent e) {
    theta+= 10; // <------------I think prooblem was here..
    if (theta==360){
        theta=0;
    }
    repaint();
}
于 2012-10-24T14:10:55.023 に答える
-2

問題は、2つの変更を加える必要があることでした。

// 1.
g2.rotate(theta,125,125);

// 2.
super.paint(g);
于 2012-10-24T14:31:03.740 に答える