import java.awt.Font;
import java.awt.geom.AffineTransform;
import java.awt.Graphics2D;
import java.awt.Graphics;

/**
  * Partial program for flipping, mirroring and rotating images.
  */
private void buildTransform ()
   {
   // build Affine transform to flip, mirror and rotate.
   transform = new AffineTransform();

   /* Temporarily move the origin to the center of the image.
      All transforms are symmetrical about this point.
      Otherwise the image would rotate
      around the upper left corner, and disappear off screen. */
   transform.translate( getWidth() / 2.0, getHeight() / 2.0 );

   if ( flip )
      {
      /* turn image upside down */
      transform.scale( 1.0, -1.0 );
      }
   if ( mirror )
      {
      /* mirror image left to right */
      transform.scale( -1.0, 1.0 );
      }
   if ( rotateDegrees != 0 )
      {
      if ( rotateDegrees % 90 == 0 )
         {
         /* rotate image in 90 degree chunks, +ve is anticlockwise */
         transform.quadrantRotate( rotateDegrees / 90 );
         }
      else
         {
         /* rotate image by some odd angle */
         transform.rotate( Math.toRadians( rotateDegrees ) );
         }
      }
   // put origin back to upper left corner
   transform.translate( -getWidth() / 2.0, -getHeight() / 2.0 );
   }

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

   // access extended 2D graphics methods.
   Graphics2D g2 = (Graphics2D)g;

   // save original transform
   AffineTransform origTransform = g.getTransform();

   // hook up our new transform
   g.setTransform ( transformer );

   /*
    * center Image in box, normally should exactly fill the box. If we
    * overflow, no problem, drawImage will clip.
    */
   g.drawImage( image, /* Image to draw */
                0, /* x */
                0, /* y */
                width, /* width */
                height, /* height */
                this );/* this component */

   // restore original transform
   g.setTransform( origTransform );

   }