How to rotate an ellipse around the center of prog

2019-08-21 07:49发布

So I used tutorials from http://zetcode.com/tutorials/javagamestutorial/basics/ and I'm using the Donut program. For anyone unfamiliar it does this http://zetcode.com/img/gfx/javagames/donut.png I want to make the ellipses rotate around the center of the window, to make it look like it's moving in a circle.

The code so far is the code from the webpage.

package donut;

import javax.swing.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;

public class Board extends JPanel{
public void paint(Graphics g)
{
    super.paint(g);

    Graphics2D g2 = (Graphics2D) g;

    RenderingHints rh =
            new RenderingHints(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);

    rh.put(RenderingHints.KEY_RENDERING,
            RenderingHints.VALUE_RENDER_QUALITY);

    g2.setRenderingHints(rh);

    Dimension size = getSize();
    double w = size.getWidth();
    double h = size.getHeight();

    Ellipse2D e = new Ellipse2D.Double(0, 0, 80, 130);
    g2.setStroke(new BasicStroke(1));
    g2.setColor(Color.gray);


    for (double deg = 0; deg < 360; deg += 5) {
        AffineTransform at =
                AffineTransform.getTranslateInstance(w / 2, h/2);
        at.rotate(Math.toRadians(deg));
        g2.draw(at.createTransformedShape(e));
    }


    while(true)
    {

    }
}
}

I can usually get the theory behind how to do it at the least(I am very new to programming, especially GUIs and graphics) but I dont know how this time. Maybe, RotateAnimation or something similar? Hopefully I dont get flagged for being a noob

1条回答
放荡不羁爱自由
2楼-- · 2019-08-21 08:34

You can't do that for loop in the paint method as it will compete all looping instantly resulting in no aniation. Also a while (true) loop in paint or anywhere in the event thread will prevent your program from painting which will cripple your program to a stand-still. Instead:

  • Use a Swing Timer to drive your animation.
  • Create your Ellipse instance in the class, not in a painting method.
  • In the Timer increment your angle of rotation and call repaint().
  • Override paintComponent not paint
  • Only do painting in this method, no logic. The logic goes in your Timer.
  • In the paintComponent method, use the angle changed by the Timer to do your affine transformation and draw the correct ellipse.
  • Search this site for Java Swing animation for examples as this has been asked many times resulting in many sample programs for this (some written by me).

For example:

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;

@SuppressWarnings("serial")
public class RotateEllipse extends JPanel {
   private static final double ELLIPSE_W = 80;
   private static final double ELLIPSE_H = 130;
   private static final int PREF_W = 400;
   private static final int PREF_H = 400;
   private static final Stroke STROKE = new BasicStroke(5f);
   private static final Color ELLIPSE_COLOR = Color.red;
   private static final Color BACKGROUND = Color.black;
   private static final double ELLIPSE_X = PREF_W / 2 - ELLIPSE_W / 2;
   private static final double ELLIPSE_Y = PREF_H / 2 - ELLIPSE_H / 2;
   private static final int TIMER_DELAY = 15;
   private static final double DELTA_THETA = Math.toRadians(2);

   private Ellipse2D ellipse2D;
   private AffineTransform transform = new AffineTransform();
   private double theta = 0;

   public RotateEllipse() {
      ellipse2D = new Ellipse2D.Double(ELLIPSE_X, ELLIPSE_Y, ELLIPSE_W,
            ELLIPSE_H);
      setBackground(BACKGROUND);
      new Timer(TIMER_DELAY, new TimerListener()).start();
   }

   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g.create();
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
      g2.setStroke(STROKE);
      g2.setColor(ELLIPSE_COLOR);
      g2.setTransform(transform);
      g2.draw(ellipse2D);
      g2.dispose();
   }

   private class TimerListener implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         theta += DELTA_THETA;
         transform = AffineTransform.getRotateInstance(theta, 
               ELLIPSE_X + ELLIPSE_W / 2, ELLIPSE_Y + ELLIPSE_H / 2);
         repaint();
      }
   }

   private static void createAndShowGUI() {
      RotateEllipse paintEg = new RotateEllipse();

      JFrame frame = new JFrame("RotateEllipse");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(paintEg);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGUI();
         }
      });
   }
}
查看更多
登录 后发表回答