Difference between revisions of "JavaScript Scripting"

(Importing packages and classes: Package -> Packages)
Line 10: Line 10:
  // Import all classes under java.io.*
  // Import all classes under java.io.*
  // Import a single class instead
  // Import a single class instead
=== Creating import namespaces ===
=== Creating import namespaces ===

Revision as of 13:47, 16 October 2008

Javascript tutorial for ImageJ

Language basics

Importing packages and classes

By default, all ImageJ and java.lang.* classes are imported.

You can specify further imports by:

// Import all classes under java.io.*

// Import a single class instead

Creating import namespaces

 var awt_bindings = new JavaImporter(Packages.java.awt.Frame, Packages.java.awt.Button);
 with (awt_bindings) {
   // imported classes visible ONLY in this block
   win = new Frame("Title");
   b = new Button("Press me");

Inspecting fields and methods of an object

So you are returned an object for a function and you don't know what is it.

To print its class within the interpreter:

 ob = ...

or to the log window:

 ob = ...

To print the list of methods it has, with their return types and argument types:

 ob = ...
 m = ob.getClass().getMethods();
 for (i=0; i<m.length; i++) IJ.log(m[i]);

ImageJ interaction

Opening and creating ImageJ images

 imp = new Opener().openImage("/path/to/image.jpg");
 // do some processing
 // ...
 // from scratch:
 width = 512
 height = 512
 pixels = new java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, width * height);
 // process the pixels
 // ...
 channel = new java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 256);
 for (i=0; i<channel.length; i++) channel[i] = Integer(i).byteValue();
 cm = new LUT(channel, channel, channel);
 imp = new ImagePlus("the title", new ByteProcessor(width, height, pixels, cm));
 // a bit less from scratch
 imp = ImagePlus("the title", new ByteProcessor(512, 512));
 pixels = imp.getProcessor().getPixels();
 // do some processing ...
 // ...

Running ImageJ commands

To launch a command:

 // in a separate thread:
 // instead, waiting until it finishes:

Inspect java methods and fields in an object

To print the static fields and methods of ImagePlus class:

 s = "";
 for (a in ImagePlus) { s += " " + a; }


To print the fields and methods of an instance of ImagePlus (i.e. an image that already exists):

 // get the current image
 imp = IJ.getImage();
 // print fields and methods
 s = ""; for (a in imp) { s += " " + a; }

... which prints all method names such as getStatistics isHyperStack etc. and fields like width and height (because there are public 'get' methods for it such as getWidth() and getHeight() .)

Advanced scripting

To create an ImageListener without declaring a new class that implements such java interface, simply use a function that will be mapped to all its methods (as long as they have the same signature, which they do in this case):

 ImagePlus.addImageListener( function (imp, name) {
       if (name == "imageOpened") {
               IJ.log("Opened image: " + imp);
       } else if (name == "imageClosed") {
               IJ.log("Closed image: " + imp);
       } else if (name == "imageUpdated") {
               IJ.log("Updated image: " + imp);

Alternatively, one can create an object with declared functions inside to assign then to an anonymous class created on the fly from an interface:

 body = {
   run: function () {
 // Runnable is an interface
 runnable = new Runnable(body);
 new Thread(runnable).start();


 new Thread( function () { IJ.log("Running!"); } ).start();

What the code above did: to look for an interface that could take a method with no arguments, represented by the function, and instantiate an anonymous class that implements such interface with the function mapped to its method.

See also an example plugin for ImageJ written in javascript.


See also the Scripting_comparisons.