import javax.swing.*; // For JPanel, etc.
import java.awt.*;           // For Graphics, etc.
import java.awt.geom.*;      // For Ellipse2D, etc.

/** A JPanel that draws a "viewport", a "sheet of paper",
 *  and a "message" under various transformations. Used
 *  to illustrate how AffineTransforms work in Java2D.
 *
 *  From tutorial on learning Java2D at
 *  http://www.apl.jhu.edu/~hall/java/Java2D-Tutorial.html
 *
 *  1998 Marty Hall, http://www.apl.jhu.edu/~hall/java/
 */

public class TransformExample extends JPanel {
  private int xOffset=25, yOffset=xOffset+20, width=120;
  private Rectangle viewport =
    new Rectangle(xOffset, yOffset, width, width);
  private Rectangle paper =
    new Rectangle(xOffset+1, yOffset+1, width-2, width-2);
  private String message = "Test";
  private double viewportXTranslation, viewportYTranslation,
                 viewportRotation;
  private double paperXTranslation, paperYTranslation,
                 paperRotation;
  private double messageXTranslation, messageYTranslation,
                 messageRotation;
  private float[] dashPattern = { 10, 2, 2, 2 };
  private Stroke viewportStroke
    = new BasicStroke(3, BasicStroke.CAP_BUTT,
                      BasicStroke.JOIN_MITER, 10,
                      dashPattern, 0);
  private RenderingHints renderHints;

  public TransformExample(double viewportXTranslation,
                          double viewportYTranslation,
                          double viewportRotation,
                          double paperXTranslation,
                          double paperYTranslation,
                          double paperRotation,
                          double messageXTranslation,
                          double messageYTranslation,
                          double messageRotation) {
    this.viewportXTranslation = viewportXTranslation;
    this.viewportYTranslation = viewportYTranslation;
    this.viewportRotation = viewportRotation;
    this.paperXTranslation = paperXTranslation;
    this.paperYTranslation = paperYTranslation;
    this.paperRotation = paperRotation;
    this.messageXTranslation = messageXTranslation;
    this.messageYTranslation = messageYTranslation;
    this.messageRotation = messageRotation;
    renderHints =
      new RenderingHints(RenderingHints.KEY_ANTIALIASING,
                         RenderingHints.VALUE_ANTIALIAS_ON);
    renderHints.put(RenderingHints.KEY_RENDERING,
                    RenderingHints.VALUE_RENDER_QUALITY);
    setFont(new Font("Serif", Font.BOLD, 30));
    setPreferredSize(new Dimension(150, 175));
    setSize(150, 175);
  }

  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D)g;
    g2d.setRenderingHints(renderHints);
    g2d.setPaint(Color.lightGray);
    transform(g2d, paperXTranslation, paperYTranslation,
              paperRotation);
    g2d.fill(paper);
    transform(g2d, -paperXTranslation, -paperYTranslation,
              -paperRotation);
    g2d.setPaint(Color.black);
    transform(g2d, messageXTranslation, messageYTranslation,
              messageRotation);
    g2d.drawString(message, xOffset+30, yOffset+width/2+15);
    transform(g2d, -messageXTranslation, -messageYTranslation,
              -messageRotation);
    transform(g2d, viewportXTranslation, viewportYTranslation,
              viewportRotation);
    g2d.setStroke(viewportStroke);
    g2d.draw(viewport);
    transform(g2d, -viewportXTranslation, -viewportYTranslation,
              -viewportRotation);
  }

  private void transform(Graphics2D g2d, double xTranslation,
                         double yTranslation, double rotation) {
    g2d.translate(xTranslation, yTranslation);
    g2d.rotate(rotation);
  }
}


