OCaml-Java: developing applets


This page contains the information explaining how to develop Java applets using OCaml-Java. The first sections describe how to link applets respectively based on the Java AWT toolkit, the Java Swing toolkit, and the OCaml Graphics module. Then, a section explains how to deploy compiled applets. Finally, the last section consists in a complete example of a Swing-based applet.

AWT applets

To produce an AWT applet using the ocamljava compiler, it is necessary to link with the command-line switch -applet awt. In order to be able to successfully link with this command-line switch, the main module has to abide the module type defined as JavaApplet.AWT. The definition of this module type is:

val applet_info : java'lang'String java_instance
val parameter_info : parameter_info
val init : java'applet'Applet java_instance -> unit
val start : java'applet'Applet java_instance -> unit
val stop : java'applet'Applet java_instance -> unit
val destroy : java'applet'Applet java_instance -> unit

The bare values applet_info and parameter_info define the values returned respectively by the getAppletInfo() and getParameterInfo() methods of the produced applet. The functions init, start, stop, and destroy give the implementations of the applet methods having the very same names. The passed parameter is simply the applet instance.

Swing applets

An applet based on Swing is very similar to an applet based on AWT. The link is done by passing the -applet swing command-line switch, which implies that the main module should abide the JavaApplet.Swing module type. This module type only differs from JavaApplet.AWT in the type of the parameter passed to the init, start, stop, and destroy functions: javax'swing'JApplet java_instance instead of java'applet'Applet java_instance.

Graphics applets

An applet based on the OCaml Graphics module is slightly different from an applet based on either AWT or Swing. The link is done by passing the -applet graphics command-line switch, which implies that the main module should abide the JavaApplet.Graphics module type. This module type is different from JavaApplet.AWT and JavaApplet.Swing in two aspects:

  • the parameter passed to the init, start, stop, and destroy functions is () rather than the applet instance;
  • an additional function, namely run, with type JavaApplet.graphics_event -> unit is requested.

The run function is called for every event happening on the canvas containing the drawing area of the Graphics module. For example, the following module defines an applet that draws a small square around every pixel clicked by the user:

let applet_info = JavaString.of_string "simple Graphics applet"

let parameter_info = JavaApplet.parameter_info_of_list []

let init () = ()

let start () = ()

let run event =
  if event.JavaApplet.button then begin
    let x = event.JavaApplet.mouse_x in
    let y = event.JavaApplet.mouse_y in
    Graphics.draw_rect (x - 5) (y - 5) 11 11
  end

let stop () = ()

let destroy () = ()

Deployment

In order to embed an applet into an HTML page, it is necessary to specify its archive, and the fully-qualified name of the class implementing the applet. The archive is simply the jar file produced by the ocamljava compiler. When using the applet linking mode, ocamljava produces a class named ocamljavaApplet located in the package specified by the -java-package command-line switch (defaulting to pack).

The OCaml-Java runtime library relies on operations that needs privileged rights to be used inside an applet. For this very reason, it is mandatory to sign the jar file containing the applet. This is done by executing jarsigner <jar-file> <alias> where alias refers to an alias of a crt file. If you have no signing key, it is usually possible to create one and export it to a crt file through:

keytool -genkey -keyalg rsa -alias my_alias
keytool -export -alias my_alias -file cert.crt

Example

In this section, we will develop a simple Swing-based applet. Its GUI will contain a text field and a button, and a click on the button will trigger a modal dialog displaying the contents of the text field. The initial contents of the text field we be retrieved from an applet parameter. The code of the applet heavily relies on the Java extensions that are presented here.

First, we have to define the description of the applet and its parameters. This is done through the following code, using the JavaString module to convert OCaml strings into Java ones:

let applet_info = JavaString.of_string "Applet example"
let parameter_info =
  JavaApplet.(parameter_info_of_list [
              { param_name = JavaString.of_string "default_text";
                param_type = JavaString.of_string "string";
                param_desc = JavaString.of_string "initial value of text field" }])

Then, we have to provide an init function that is responsible for the GUI creation:

let init japplet =
  (* retrieve the parameter value *)
  let text =
    Java.call "JApplet.getParameter(_)"
      japplet
      (JavaString.of_string "default_text") in
  (* build a textfield and a button *)
  let textfield = Java.make "JTextField(String)" text in
  let button = Java.make "JButton(String)" (JavaString.of_string "open") in
  (* add an event handler to the button *)
  Java.call "JButton.addActionListener(_)"
    button
    (Java.proxy "ActionListener" (object
      method actionPerformed _ =
        let contents = Java.call "JTextField.getText()" textfield in
        ignore (Java.call "JOptionPane.showMessageDialog(_,_)" japplet contents)
    end));
  (* add the textfield and the button to the GUI *)
  Java.call "JApplet.add(Component,Object)"
    japplet
    textfield
    (Java.get "BorderLayout.CENTER" ());
  Java.call "JApplet.add(Component,Object)"
    japplet
    button
    (Java.get "BorderLayout.EAST" ())

Although we do not have any action to perform for the start, stop, and destroy events, we still have to provide the related functions. Otherwise, ocamljava will fail to link, indicating that the module does not abide to the applet module type signature. We therefore add the following no-op functions:

let start _ = ()
let stop _ = ()
let destroy _ = ()

We can now compile and link the code, through the following commands:

ocamljava -java-extensions -c source.ml
ocamljava -applet swing -o app.jar javalib.cmja source.cmj

It is also necessary to sign the applet through:

jarsigner app.jar <em>alias</em>

The last step to be able to test the applet is to write an HTML file embedding it, for example:

<html>
  <head>
    <title>Applet test</title>
  </head>
  <body>
    <applet code="pack.ocamljavaApplet"
            archive="path/to/app.jar"
            width="400"
            height="32">
      <param name="default_text" value="enter a text here"/>
    </applet>
  </body>
</html>

The applet can now be tested by opening the HTML file in a Java-capable browser. It is noteworthy that the user will have to validate the applet, as it is a signed one.