2
 import javax.swing.*;
 import java.awt.*;

 public class JFrameAnimationTest extends JFrame {
     public static void main(String[] args) throws Exception{
        AnimationPanel animation = new AnimationPanel();
        JFrameAnimationTest frame = new JFrameAnimationTest();
        frame.setSize(600, 480);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(animation);
        frame.setVisible(true);        
        for(int i = 0; i < 100; i++) {
            animation.incX(1);
            //animation.incY(1);
            animation.repaint();
            Thread.sleep(10);
        }
    }
}

class AnimationPanel extends JPanel {

    int x = 10;
    int y = 10;   

  public AnimationPanel() {        
  }

  @Override
  protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.setColor(Color.BLUE);
      g.drawRect(x, y, 20, 20);
      g.fillRect(x, y, 20, 20);
  }

  protected void incX(int X) {
      x += X;
  }

  protected void incY(int Y) {
      y += Y;
  }
}

So anyways theres my code. It probably looks a bit jumbled as I am not used to stackoverflow just yet so I apologize.

Here's my question: This program makes this small rectangle slowly move to the right; how can I add rotation to the rectangles movement during that time period?

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Ty_
  • 828
  • 1
  • 11
  • 21

1 Answers1

3

Note: I haven't actually compiled this code, but you get the gist.

public void paintComponent( Graphics g )
{
    super.paintComponent( g );
    Graphics2D g2d = (Graphics2D) g;

    // The 20x20 rectangle that you want to draw
    Rectangle2D rect = new Rectangle2D.Double( 0, 0, 20, 20 );

    // This transform is used to modify the rectangle (an affine
    // transform is a way to do operations like translations, rotations,
    // scalings, etc...)
    AffineTransform transform = new AffineTransform();

    // 3rd operation performed: translate the rectangle to the desired
    // x and y position
    transform.translate( x + 10, y + 10 );

    // 2nd operation performed: rotate the rectangle around the origin
    transform.rotate( rotation );

    // 1st operation performed: translate the rectangle such that it is
    // centered on the origin
    transform.translate( -10, -10 );

    // Apply the affine transform
    Shape s = transform.createTransformedShape( rect );

    // Fill the shape with the current paint
    g2d.fill( s );

    // Stroke the edge of the shape with the current paint
    g2d.draw( s );
}

Also note that you should really be using something like a javax.swing.Timer when you modify x, y, and rotation and when you call repaint(). That way all of it happens on the event dispatch thread.

lifelongcoug
  • 678
  • 6
  • 12
  • @EW Added some comments... I hope they help. Just keep in mind that with AffineTransform the operations are essentially performed in reverse order (when created as shown). – lifelongcoug Oct 12 '12 at 04:51
  • When you call the rotate method I have two questions: 1) Where is "rotation" coming from? Is it a constant or what? 2) By how much does it rotate the object? – Ty_ Oct 12 '12 at 04:54
  • @EW The rotation would be maintained in your `AnimationPanel` - just like you are maintaining `x` and `y`. I just used an example name for the variable you would need. – lifelongcoug Oct 12 '12 at 04:57
  • Okay thanks! I am going to do some reading on AffineTransform, but this really helped me, quite a lot. Big ups man! – Ty_ Oct 12 '12 at 05:02
  • 1
    @EW Glad it helped. I also failed to note that you also need to create and initialize the panel and frame on the event dispatch thread. Just surround your code with `SwingUtilities.invokeLater( new Runnable() { public void run() { /* your code */ } } )`. In general it would be good to read this article: [The Event Dispatch Thread](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html) – lifelongcoug Oct 12 '12 at 05:29