Example of an Oberon-2 compilation for Java
Canterbury Oberon-2 for Java can be easily called from a simple command prompt. For example, the compiler package has a click animation sample program as follows:
Slides.obn MODULE Slides; (* A simple Web page click animation entirely done *) (* in Canterbury Oberon-2 for Java. *) (* Last update: Sep 14, 1998 *) (* *) (* (c) 1998 by Mill Hill & Canterbury Corporation, Ltd. *) (*$XF+ Extended function designator usage *) IMPORT SYSTEM, java_applet_Applet, java_lang_Runnable, java_lang_Thread, java_awt_Image, java_awt_Graphics, java_awt_Event, java_lang_String, java_lang_Exception; TYPE (* ClickAnimation extends Java class java.applet.Applet and implements Java interface java.lang.Runnable *) ClickAnimation* = RECORD ( java_applet_Applet.Applet, java_lang_Runnable.Runnable ) animationThread : java_lang_Thread.POINTER_TO_Thread; cur : INTEGER; frame : ARRAY 4 OF java_awt_Image.POINTER_TO_Image; mouseClick : BOOLEAN; END; (* Oberon-2 always regards constructors as type-bound procedures, but Java needs to know that it is a constructor, hence the need for using the JAVA CONSTRUCTOR directive. *) (*$JAVA CONSTRUCTOR *) PROCEDURE( VAR Self : ClickAnimation) construct*(); BEGIN Self._init_^(); (* call superclass constructor *) END construct; (* The type-bound procedure "init" overrides the one inherited from Java class java.applet.Applet. This procedure always gets called first in a Java applet and is responsible for intializing all the fields *) PROCEDURE( VAR Self : ClickAnimation) init*(); VAR i : INTEGER; gifName : ARRAY 9 OF CHAR; PROCEDURE JavaString ( s : ARRAY OF CHAR ) : java_lang_String.POINTER_TO_String; VAR Result : java_lang_String.POINTER_TO_String; VAR i : LONGINT; BEGIN (* convert an ARRAY OF CHAR to a java.lang.String object *) NEW( Result, SYSTEM.ADR(s) ); i := Result.indexOf( 0 ); IF i >= 0 THEN Result := Result.substring( 0, i ); END; RETURN Result; END JavaString; BEGIN (* set display size for applet *) Self.resize(300,300); (* get the GIF-formatted images *) FOR i := 0 TO 3 DO CASE i OF | 0 : gifName := 'col1.gif'; | 1 : gifName := 'col2.gif'; | 2 : gifName := 'col3.gif'; ELSE gifName := 'col4.gif'; END; Self.frame[i] := Self.getImage ( Self.getDocumentBase(), JavaString(gifName) ); END; (* no mouse click yet *) Self.mouseClick := FALSE; END init; (* The type-bound procedure "start" overrides java.applet.Applet.start. It is called by the browser or applet viewer to inform this applet that it should start its execution. It is called after the init method and each time the applet is revisited in a Web page. *) PROCEDURE( VAR Self : ClickAnimation) start*(); BEGIN (* Create a new thread for class ClickAnimation. Canterbury uses an extended standard procedure NEW, with an optional second parameter for a constrcutor call *) NEW( Self.animationThread, SYSTEM.ADR(Self) ); (* The start() method spawns the animation thread in order for the animation to run the first time *) Self.animationThread.start(); (* Once the animation thread is started, it calls the run() method. *) END start; (* The type-bound procedure "stop" overrides java.applet.Applet.stop. It is called by the browser or applet viewer to inform this applet that it should stop its execution. It is called when the Web page that contains this applet has been replaced by another page, and also just before the applet is to be destroyed. *) PROCEDURE( VAR Self : ClickAnimation) stop*(); BEGIN (* stop the animation thread *) Self.animationThread.stop(); END stop; (* The type-bound procedure "run" implements the one from the Java interface java.lang.Runnable. Starting the thread causes the objects "run" method to be called in that separately executing thread. *) PROCEDURE( VAR Self : ClickAnimation) run*(); BEGIN (* If there was no mouse click repaint the first frame, else repaint the next one. *) IF (~Self.mouseClick) THEN Self.cur := 0; Self.repaint(); ELSE Self.mouseClick := FALSE; Self.cur := Self.cur + 1; IF (Self.cur > 3) THEN Self.cur := 0; END; Self.repaint(); END; END run; (* The type-bound procedure "paint" overrides an inherited one. It is responsible for painting the applets display area. *) PROCEDURE( VAR Self : ClickAnimation) paint* ( g : java_awt_Graphics.POINTER_TO_Graphics ); BEGIN g.drawImage( Self.frame[Self.cur], 0, 0, SYSTEM.ADR(Self) ); END paint; (* Method "mouseDown" overrides an inherited one. Always called in case of a mouse button being pressed while its cursor is on the applet. *) PROCEDURE( VAR Self : ClickAnimation) mouseDown* ( e : java_awt_Event.POINTER_TO_Event; x : LONGINT; y : LONGINT ) : BOOLEAN; BEGIN Self.mouseClick := TRUE; NEW( Self.animationThread, SYSTEM.ADR(Self) ); Self.animationThread.start(); RETURN TRUE; END mouseDown; END Slides.
In order to compile and execute the Slides.obn sample on a Windows system, just open a DOS-prompt and enter the following commands (shown here in bold font):
C:\com.mhccorp\mhc\obn\samples\slides>java mhc.obn Slides -m -r Oberon-2 2.5.xx (c) 1998-2006 J.Neuhoff (www.mhccorp.com) Compiling: C:\com.mhccorp\mhc\runtime\obn\SYSTEM.obn Importing Java class: java.applet.Applet Importing Java class: java.lang.Runnable Importing Java class: java.lang.Thread Importing Java class: java.awt.Image Importing Java class: java.awt.Graphics Importing Java class: java.awt.Event Importing Java class: java.lang.String Importing Java class: java.lang.Exception Compiling: Slides.obn Compilation done: Slides.obn C:\com.mhccorp\mhc\obn\samples\slides>javac *.java -nowarn C:\com.mhccorp\mhc\obn\samples\slides>appletviewer Slides.html C:\com.mhccorp\mhc\obn\samples\slides>
As can be seen, the command
java mhc.obn Slides -m -r
causes the file Slides.obn to be compiled into various *.java files:
Slides.java
Slides_ClickAnimation_init_Frame.java
Slides_ClickAnimation.java
SYSTEM.java
SYSTEM_*.java
The -m switch tells the compiler also to recompile other imported Oberon-2 files if they are updated. This is like a Make-utility for Oberon-2 files integrated into the Oberon-2 compiler. The -r switch causes the compiler to write the compiled runtime classes into the current working directory.
The command
javac *.java -nowarn
gets the *.java files translated into the final byte code:
Slides.class
Slides_ClickAnimation_init_Frame.class
Slides_ClickAnimation.class
SYSTEM.class
SYSTEM_*.class
Module Slides.obn has an Oberon-2 class type called ClickAnimation extending the imported class java.applet.Applet. It also declares some type-bound procedures resulting in an override of some inherited methods. In order to run ClickAnimation, an applet-tag has to be declared in an HTML-document. In this case, file Slides.html has an applet-tag as follows:
Slides.html <html> <head> <title>A simple click animation applet</title> </head> <body> <p /> <applet code="Slides_ClickAnimation.class" codebase="." name="A simple click animation applet" width="170" height="170"> </applet> </body> </html>
Calling this file using the JDK appletviewer utility:
appletviewer Slides.html
will launch the Slides_ClickAnimation.class.
