import javax.swing.JFrame; import javax.swing.JPanel; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.Container; import java.awt.Graphics; import java.awt.Color; import java.awt.Polygon; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; /** * CS2335 Lab 6 Example * *
 * SimpleAnimation.java shows the basics of how to create an animation
 * 
 *
 * @author Ted Choc
 * @version Version 1.4, February 20, 2003
 */
public class SimpleAnimation {
    /**
     * JFrame to which everything is rendered
     */
    private JFrame guiFrame;

    /**
     * Content Pane of the JFrame
     */
    private Container contentPane;

    /**
     * The panel to which all the graphics will be drawn
     */
    private JPanel graphicsPanel;

    /**
     * Determines the current rotation of the polygon
     */
    private int rotationValue = 0;

    /** 
     * Determines how the current polygon should be scaled
     */
    private double scaleValue = 1.0;

    /**
     * Determines whether to shrink or grow the polygon
     */
    private boolean increasingScale = true;

    /**
     * Determines what color the square should be
     * 0 - Red, 1 - Green, 2 - Blue
     */
    private int colorSelection = 0;

    /**
     * Determines the current color
     */
    private Color currentColor = Color.red;

    /**
     * A modifier for guiFrame
     * @param guiFrame new guiFrame
     */
    public void setGuiFrame(JFrame guiFrame) {
        this.guiFrame = guiFrame;
    }

    /**
     * A modifier for contentPane
     * @param contentPane new contentPane
     */
    public void setContentPane(Container contentPane) {
        this.contentPane = contentPane;
    }

    /**
     * A modifier for graphicsPanel
     * @param graphicsPanel new graphicsPanel
     */
    public void setGraphicsPanel(JPanel graphicsPanel) {
        this.graphicsPanel = graphicsPanel;
    }

    /**
     * An accessor for guiFrame
     * @return JFrame guiFrame
     */
    public JFrame getGuiFrame() {
        return this.guiFrame;
    }

    /**
     * An accessor for contentPane
     * @return Container contentPane
     */
    public Container getContentPane() {
        return this.contentPane;
    }

    /**
     * An accessor for graphicsPanel
     * @return JPanel graphicsPanel
     */
    public JPanel getGraphicsPanel() {
        return this.graphicsPanel;
    }

    /**
     * Create the window and sets it up for drawing
     */
    public void makeWindow() {
        guiFrame = new JFrame("Simple Animation");
        guiFrame.addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent we) {
                    System.exit(0);
                }
            });
        contentPane = guiFrame.getContentPane();
        graphicsPanel = new JPanel() {
                    public void paintComponent(Graphics g) {
                        super.paintComponent(g);
                        drawGraphics(g);
                    }
                };
        contentPane.add(graphicsPanel);
        guiFrame.setSize(500, 500);
        guiFrame.setVisible(true);
        graphicsPanel.setBackground(Color.lightGray);
    }

    /**
     * Draws the polygon on the Graphics
     * @param g the graphics object to be drawn on
     */
    public void drawGraphics(Graphics g) {
        int[] xCoord = { 200, 300, 300, 200 };
        int[] yCoord = { 200, 200, 300, 300 };
        Polygon rectangle = new Polygon(xCoord, yCoord, 4);

        //g.fillPolygon(rectangle);
        g.setColor(currentColor);
        g.fillPolygon(rotatePolygon(scalePolygon(rectangle, scaleValue),
                rotationValue));

        //g.setColor(Color.blue);
        //g.fillPolygon(rotatePolygon(rectangle, 60));
    }

    /**
     * Rotates the polygon by some angle - look into AffineTransform
     * for a better way to handle this.  This is also kind of a 
     * hack because it only works for rectangles, but it works for
     * this example
     *   Rotation Matrix
     * | cos(a) -sin(a) 0 |
     * | sin(a)  cos(a) 0 |
     * |   0       0    1 |
     * @param p polygon to be rotated
     * @param theta the angle to be rotated by
     * @return Polygon that has been rotated
     */
    public Polygon rotatePolygon(Polygon p, int theta) {
        int[] xCoord = p.xpoints;
        int[] yCoord = p.ypoints;
        int xMidpoint = ((xCoord[1] - xCoord[0]) / 2) + xCoord[0];
        int yMidpoint = ((yCoord[2] - yCoord[1]) / 2) + yCoord[1];
        p.translate(-xMidpoint, -yMidpoint);
        xCoord = p.xpoints;
        yCoord = p.ypoints;

        int[] xRotCoord = new int[p.xpoints.length];
        int[] yRotCoord = new int[p.ypoints.length];
        int numPoints = p.npoints;
        double thetaRad = Math.toRadians((double) theta);

        for (int i = 0; i < numPoints; i++) {
            xRotCoord[i] = (int) (xCoord[i] * Math.cos(thetaRad))
                + (int) (yCoord[i] * Math.sin(thetaRad));
            yRotCoord[i] = (int) (-(xCoord[i]) * Math.sin(thetaRad))
                + (int) (yCoord[i] * Math.cos(thetaRad));
        }

        Polygon rotatedP = new Polygon(xRotCoord, yRotCoord, numPoints);
        rotatedP.translate(xMidpoint, yMidpoint);
        p.translate(xMidpoint, yMidpoint);

        return rotatedP;
    }

    /**
     * Scales the polygon by the specfied amount
     * @param p polygon prior to being scaled
     * @param scalar the amount to shrink or the grow the polygon by
     * @return the polygon that has been scaled
     */
    public Polygon scalePolygon(Polygon p, double scalar) {
        int[] xCoord = p.xpoints;
        int[] yCoord = p.ypoints;
        int xMidpoint = ((xCoord[1] - xCoord[0]) / 2) + xCoord[0];
        int yMidpoint = ((yCoord[2] - yCoord[1]) / 2) + yCoord[1];
        p.translate(-xMidpoint, -yMidpoint);
        xCoord = p.xpoints;
        yCoord = p.ypoints;

        int[] xScaleCoord = new int[p.xpoints.length];
        int[] yScaleCoord = new int[p.ypoints.length];
        int numPoints = p.npoints;

        for (int i = 0; i < numPoints; i++) {
            xScaleCoord[i] = (int) (scalar * xCoord[i]);
            yScaleCoord[i] = (int) (scalar * yCoord[i]);
        }

        Polygon scaledP = new Polygon(xScaleCoord, yScaleCoord, numPoints);
        scaledP.translate(xMidpoint, yMidpoint);
        p.translate(xMidpoint, yMidpoint);

        return scaledP;
    }

    /**
     * Animates the square
     */
    public void animateGraphics() {
        ActionListener listener = new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    rotationValue = (rotationValue + 5) % 360;

                    if (increasingScale == true) {
                        if (scaleValue >= 2.5) {
                            increasingScale = false;
                        } else {
                            scaleValue = scaleValue + 0.05;
                        }
                    } else {
                        if (scaleValue <= 0.5) {
                            increasingScale = true;
                        } else {
                            scaleValue = scaleValue - 0.05;
                        }
                    }

                    if (colorSelection == 0) {
                        currentColor = new Color(currentColor.getRed() - 5,
                                currentColor.getGreen() + 5, 0);

                        if (currentColor.getRed() <= 0) {
                            colorSelection = 1;
                        }
                    } else if (colorSelection == 1) {
                        currentColor = new Color(0,
                                currentColor.getGreen() - 5,
                                currentColor.getBlue() + 5);

                        if (currentColor.getGreen() <= 0) {
                            colorSelection = 2;
                        }
                    } else {
                        currentColor = new Color(currentColor.getRed() + 5, 0,
                                currentColor.getBlue() - 5);

                        if (currentColor.getBlue() <= 0) {
                            colorSelection = 0;
                        }
                    }

                    graphicsPanel.repaint();
                }
            };

        javax.swing.Timer animation = new javax.swing.Timer(50, listener);
        animation.start();
    }

    /**
     * Creates a new SimpleAnimation and begins the animation
     * @param args Command Line Arguments
     */
    public static void main(String[] args) {
        SimpleAnimation test = new SimpleAnimation();
        test.makeWindow();
        test.animateGraphics();
    }
}