Thread Demonstration

Study this code carefully if you are planning to write an applet game involving a delay. For best performance you should only put a delay in a thread you create yourself. In order to use a thread in an Applet, you must implement the Runnable interface. We advise you to experiment thoroughly with this excellent starting code before developing your own from scratch.

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

The code of ThreadApplet.pas

namespace threads;
{
  Author: Michael McGuffin
  Converted to Oxygene for Java by Dharmesh Tailor
}
interface

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

type
  ThreadApplet = public class(Applet, Runnable)
  private
    var width, height : Integer;
    var i : Integer := 0;
    var t : Thread := nil;
    var threadSuspended : Boolean;
  public
    method init; override;
    method destroy; override;
    method start; override;
    method stop; override;
    method run;
    method paint(g : Graphics); override;
  end;

implementation

//Executed when the applet is first created
method ThreadApplet.init;
begin
  System.out.println('init: begin');
  width := getSize.width;
  height := getSize.height;
  setBackground(Color.black);
  System.out.println('init: end');
end;

//Executed when the applet is destroyed
method ThreadApplet.destroy;
begin
  System.out.println('destroy');
end;

//Executed after the applet is created
//also whenever the browser returns to the page containing the applet
method ThreadApplet.start;
begin
  System.out.println('start: begin');
  if (t = nil) then
    begin
      System.out.println('start: creating thread');
      t := new Thread(self);
      System.out.println('start: starting thread');
      threadSuspended := false;
      t.start;
    end
  else
    begin
      if threadSuspended then
        begin
          threadSuspended := false;
          System.out.println('start: notifying thread');
          locking self do
            begin
              notify;
            end;
        end;
    end;
  System.out.println('start: end');
end;

//Executed whenever the browser leaves the page containing the applet
method ThreadApplet.stop;
begin
  System.out.println('Stop: begin');
  threadSuspended := true;
end;

//Executed within the thread that this applet created
method ThreadApplet.run;
begin
  System.out.println('run: begin');
  try
    while (true) do
      begin
        System.out.println('run: awake');

        //Where the thread does some work
        inc(i);
        if (i = 10) then
          begin
            i := 0;
          end;
        showStatus('i is ' + i);

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

method ThreadApplet.paint(g : Graphics);
begin
  System.out.println('paint');
  g.setColor(Color.green);
  g.drawLine(width, height, i * width / 10, 0);
end;

end.

A minimal project file threads_applet.oxygene

Execute the compiler by typing at the command prompt (with the current directory set to the location of this project file and the source file):

msbuild threads_applet.oxygene
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <PropertyGroup>    
    <OutputType>Library</OutputType>   
  </PropertyGroup>  
  <ItemGroup>
    <Reference Include="rt.jar" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="ThreadApplet.pas" />
  </ItemGroup>
  <Import Project="$(MSBuildExtensionsPath)\RemObjects Software\Oxygene\RemObjects.Oxygene.Cooper.targets" />
</Project>

Web page threads.html to run the applet

<!DOCTYPE html SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Thread Test</title>
  </head>
  <body>
    <center>
      <h3>Thread Test</h2>   
      <p>Java must be enabled.</p>  
      <applet archive="threads.jar" code="threads/ThreadApplet.class" 
                width="200" height="200" />    
    </center>
  </body>
</html>

RemObjects C# Version of ThreadApplet

// Author: Michael McGuffin
// Converted to Oxygene for Java by Dharmesh Tailor then
//converted to RemObjects C# for Java by Norman Morrison
using java.util;
using java.applet;
using java.awt;

namespace threads_applet_cs
{
  public class MyApplet: Applet, Runnable
  {
    private Integer width, height;
    private Integer i = 0;
    private Thread t = null;
    private Boolean threadSuspended;

    public override void init()
    {
      System.@out.println("init: begin");
      width = getSize().width;
      height = getSize().height;
      setBackground(Color.black);
      System.@out.println("init: end");
    }

    public override void  destroy()
    {
     System.@out.println("destroy");
    }

    //Executed after the applet is created
    //also whenever the browser returns to the page containing the applet
    public override void start()
    {
      System.@out.println("start: begin");
      if (t == null) 
      {
        System.@out.println("start: creating thread");
        t = new Thread(this);
        System.@out.println("start: starting thread");
        threadSuspended = false;
        t.start();
      }
      else
      {
        if (threadSuspended) 
        {
          threadSuspended = false;
          System.@out.println("start: notifying thread");
          lock(this) 
          {
            notify();
          }
        }
        System.@out.println("start: end");
      }
    } 

    //Executed whenever the browser leaves the page containing the applet
    public override void  stop()
    {
      System.@out.println("Stop: begin");
      threadSuspended = true;
    }

    //Executed within the thread that this applet created
    public void run()
    {
      System.@out.println("run: begin");
      try
      {
        while (true) 
        {
          System.@out.println("run: awake");

          //Where the thread does some work
          inc(i);
          if (i == 10) 
          {
            i = 0;
          }
          showStatus("i is " + i);

          //Thread checks to see if it should suspend itself
          if (threadSuspended) 
          {
            lock(this) 
            {
              while (threadSuspended) 
              {
                System.@out.println("run: waiting");
                wait();
              }
            }
          }
          System.@out.println("run: requesting repaint");
        
          repaint();
          System.@out.println("run: sleeping");
          t.sleep(1000); //Interval given in milliseconds         
        }
      }
      catch  (InterruptedException e ){} 
      System.@out.println("run: end");
    }
    
    public override void paint(Graphics g)
    {      
      System.@out.println("paint");
      g.setColor(Color.green);
      g.drawLine(width, height, i * width / 10, 0);
    }
  }
}


Programming - a skill for life!

Mouse and keyboard input, graphics (including Graphics2D), threads and widgets in Oxygene for Java applets