Graphics2D Rotation Applet

This demonstration shows how you can repeatedly rotate a rectangle, in this case to represent the second hand of a clock. The start method creates and starts the thread that the run method uses. The run method should change the value of variable(s) used in the paint method. In this applet run simply increments i. The run method calls repaint (to run the paint method) then pauses the thread with the sleep instruction. The parameters for getRotateInstance method used in the paint code are the angle of rotation in radians followed by the x and y coordinates of the anchor point.

You can compare this code with the RemObjects C# version below.

The next page demonstrates rotated text.

namespace rotation_demo;
// Thread code based on an applet by Michael McGuffin which was
// converted to Oxygene for Java by Dharmesh Tailor
interface

uses
  java.util,
  java.applet.*,
  java.awt.*;

type
  RotationApplet = public class(Applet, Runnable)
  private
    const HAND_WIDTH = 5;
    var hand_length, hand_long, width, height : integer;
    var i : Integer := 0;
    var t : Thread := nil;
    var rect : Rectangle2D;
    var at_rotate : AffineTransform;
    var threadSuspended : Boolean;
  public
    method init; override;
    method start; override;
    method stop; override;
    method run;
    method paint(g : Graphics); override;
  end;

implementation

//Executed when the applet is first created
method RotationApplet.init;
begin
  width := getSize.width;
  height := getSize.height;
  hand_length := width * 2 / 5;  // Assuming a square applet
  hand_long := hand_length * 4 / 5; // Distance from the spindle to the tip
  rect := new Rectangle2D.Float(width / 2 - HAND_WIDTH / 2, height / 2 - hand_long , HAND_WIDTH, hand_length);
  setBackground(Color.black);
end;

//Executed after the applet is created
//also whenever the browser returns to the page containing the applet
method RotationApplet.start;
begin
  if t = nil then
    begin
      t := new Thread(self);
      threadSuspended := false;
      t.start;
    end
  else
    begin
      if threadSuspended then
        begin
          threadSuspended := false;
            locking self do
            begin
              notify;
            end;
        end;
    end;
end;

//Executed whenever the browser leaves the page containing the applet
method RotationApplet.stop;
begin
  threadSuspended := true;
end;

//Executed within the thread that this applet created
method RotationApplet.run;
begin
  try
    while true do
      begin
         //Where the thread does some work
        inc(i);

        //Thread checks to see if it should suspend itself
        if threadSuspended then
          begin
            locking self do
              begin
                while threadSuspended do
                  begin
                    wait;
                  end;
              end;
          end;
        repaint;
        t.sleep(1000); //Interval given in milliseconds
     end;
  except
    on e : InterruptedException do
      begin
      end;
  end;
end;

method RotationApplet.paint(g : Graphics);
var
  g2 : Graphics2D;
begin
  g2 := Graphics2D(g);
  var aT : AffineTransform := g2.getTransform;  //save existing transform
  at_rotate  := AffineTransform.getRotateInstance(i * Math.PI / 30, width / 2, height / 2);
  g2.transform(at_rotate);
  g2.setColor(Color.green);
  g2.fill(rect);
  g2.setTransform(aT); //restore original transform
end;

end.

RemObjects C# Version of Rotation Applet

// Thread code based on an applet by Michael McGuffin which was
// converted to Oxygene for Java by Dharmesh Tailor which was
// converted to RemObjects C# for Java by Norman Morrison
using java.util;
using java.applet;
using java.awt;
using java.awt.geom;

namespace rotation_applet_cs
{
  public class MyApplet: Applet, Runnable
  {
    private Integer HAND_WIDTH = 5;
    private Integer hand_length, hand_long, width, height;
    private Integer i = 0;
    private Thread t = null;
    private Rectangle2D rect;
    private AffineTransform at_rotate;
    private Boolean threadSuspended;

    public override void init()
    {
      width = getSize().width;
      height = getSize().height;
      hand_length = width * 2 / 5;  // Assuming a square applet
      hand_long = hand_length * 4 / 5; // Distance from the spindle to the tip
      rect = new Rectangle2D.Float(width / 2 - HAND_WIDTH / 2, height / 2 - hand_long , HAND_WIDTH, hand_length);
      setBackground(Color.black);
    }

    //Executed whenever the browser leaves the page containing the applet
    public override void stop()
    {
      threadSuspended = true;
    }

    //Executed after the applet is created
    //also whenever the browser returns to the page containing the applet
    public override void start()
    {
      if (t == null)
      {
        t = new Thread(this);
        threadSuspended = false;
        t.start();
      }
      else
      {
        if (threadSuspended) 
        {
          threadSuspended = false;
          lock(this) 
          {
            notify();
          }
        }
      }
    }

    //Executed within the thread that this applet created
    public void run()
    {
      try
      {
        while (true) 
        {
          //Where the thread does some work
          inc(i);

          //Thread checks to see if it should suspend itself
          if (threadSuspended) 
          {
            lock (this)
            {
              while (threadSuspended) 
              {
                wait();
              }
            }
          }
          repaint();
          t.sleep(1000); //Interval given in milliseconds
        }
      }
      catch ( InterruptedException e ){}
    }
    
    public override void paint(Graphics g)
    {
      Graphics2D g2;

      g2 = (Graphics2D)(g);
      AffineTransform aT = g2.getTransform();  //save existing transform
      at_rotate  = AffineTransform.getRotateInstance(i * Math.PI / 30, width / 2, height / 2);
      g2.transform(at_rotate);
      g2.setColor(Color.green);
      g2.fill(rect);
      g2.setTransform(aT); //restore original transform
    }
  }
}

Programming - a skill for life!

Applets using Graphics2D for transforms, gradient painting and pixel drawing in Oxygene for Java