Creating an ImageListener in Javascript

javascript
overlay
Tags: #<Tag:0x00007fd54823cda8> #<Tag:0x00007fd54823c9c0>

#1

I am writing a JS script that, amongst other things, needs to draw an overlay over the current image.
The overlay will change depending on the slice of the image, so the overlay for slice 1 will be different from slice 2, 3, and so on.

I have successfully created a function that draws the overlay, but now I would like to call it every time the user changes slice. I have done this in the past in Java by creating an ImageListener but I can’t quite figure out how to do it in JS.

The ImagePlus help page mentions an addImageListener method which sounds promising, but if I try:

var im = IJ.getImage();

im.addImageListener(function (im, event)
	{
    ...
	});

I get this error

TypeError: img["filename.tif" (-2), 8-bit, 800x600x1x1207x1] has no such function "addImageListener"

Any suggestion on how to handle this?


#2

It is a static method as shown in the API and as an example here (scroll down):

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);
          }
    });

Also an alternative implementation is given in the docs.

body = {
  run: function () {
    IJ.log("Running!");
  }
}
// Runnable is an interface
runnable = new Runnable(body);
new Thread(runnable).start();

The listener can be tested here (if it fullfills your expectations):

The Plugins/Utilities/Monitor Events command uses this interface.

As noted here:

https://imagej.nih.gov/ij/developer/api/ij/ImageListener.html

However I haven’t tested this in JavaScript.


#3

Thank you for your reply Bio7

So, using the code from that help page, will give me this error:

Cannot cast jdk.nashorn.internal.objects.ScriptFunctionImpl to ij.ImageListener

I therefore changed it to:

ImagePlus.addImageListener(new ImageListener(function (imp, name) {...}));

Note: this requires importClass(Packages.ij.ImageListener);

Now, this creates the ImageListener, however throws an exception everytime I change slice

Exception in thread "zSelector" java.lang.UnsupportedOperationException
at ij.ImageListener$$NashornJavaAdapter.imageUpdated(Unknown Source)

Any further suggestions?


#4

Here is an ImageListener in JavaScript. It is based on the Help>Examples>JavaScript>Gamma Adjuster example. The ImageListener is removed when you close the Log window.

 imageListener = new ImageListener() {
     imageOpened : function(img) {
        log("Image opened: "+img);
     },
     imageClosed : function(img) {
        log("Image closed: "+img);
     },
     imageUpdated : function(img) {
       log("Image updated: "+img);
     }
 };

 function log(msg) {
    if (!starting && WindowManager.getFrame("Log")==null)
       ImagePlus.removeImageListener(imageListener);
    else
       IJ.log(msg);
    starting = false;
 }

 ImagePlus.addImageListener(imageListener);
 starting = true;
 IJ.log("ImageListener started");

#5

The latest ImageJ daily build (1.51s33) adds the Help>Examples>JavaScript>Event Listener example, with source code is at http://wsr.imagej.net/download/Examples/JavaScript/Event_Listener.js. It implements the ImageListener, CommandListener, RoiListener and IJEventListener interfaces.