Writing Java classes that communicate with NEURON

Executing hoc statements

import neuron.Neuron;
Neuron.execute(new String("print \"Hello, World\""));

References to hoc variables

import neuron.HocVariable;
HocVariable vs = new HocVariable(new String("soma.v(.5)"))
double v = vs.getVal();
vs.setVal(-65)

References to hoc objects

Argument lists are an array of objects of type Double, String, or Object
import neuron.HocObject;
HocObject ho = new HocObject(new String("Graph"));
// following is a list of all Vectors
// in hoc it would be
// objref o
// o = new List("Vector")
HocObject ho = new HocObject(new String("List"),
			new Object[] { new String("Vector")});
Note that the Graph will not be destroyed until the first HocObject is garbage collected. This can be done explicitly with
Runtime rt = Runtime.getRuntime();
rt.runFinalization();
rt.gc();
Note that when hoc passes an objref as an argument to a java class method (or java class constructor) the object appears in java as a native java object (if its construction was as a java object, either registered with load_java or unregistered so that it appeared in hoc as a JavaObject), or a HocObject (or classes that extend HocObject such as HocVector).

Calling methods of hoc objects

Argument lists are an array of objects of type Double, String, or Object. Methods return double, String, or Object via the dMethod, sMethod, or oMethod call respectively. See the hoc vector example below.

References to hoc Vectors

HocVector extends HocObject
import neuron.HocVector
HocVector hv = new HocVector(10);
hv.oMethod(new String("indgen"), null);
double[] v = hv.fromHoc();
for (int i; i < v.length; ++i) {
	v[i] *= 2;
}
hv.toHoc(v);
double size = hv.dMethod(new String("size"), null);
String label = hv.sMethod(new String("label", null);
System.out.println(hv);// prints Vector[25] or whatever the index is
Note that when hoc passes a Vector as an argument to a java class method (or java class constructor) the Vector appears in java as a HocVector.

Java Windows and the PrintAndFileWindowManager

After a Frame title has been set and the frame has been shown on the screen, it is a good idea to call
	Neuron.windowListen(Frame, this)
This will allow the print and file window manager as well as the NEURONMainMenu/Window to manage the java Frame properly. Note that Iconify button on the title bar of the java window means "hide" in this case. Also, be aware that the default action of a JFrame when the close button is pressed is to "hide". This can be changed with Frame.setDefaultCloseOperation(int); The hoc window for this java frame references the hoc object for the java object. The hoc object is unreferenced when the window is closed (but not when it is hidden). The "this" reference is necessary for saving the java object that owns the window in a session file as well as the window's position and size. On retrieval the java object will be created and the java window will be moved and sized to the saved location. For most java objects this will not be sufficient information to reconstruct the object's data and the java class implementation will have to provide one or more of the special methods,
public int hocSessionPriority()
public char[] hocSessionSave(String sfname)
If the hocSessionPriority method exists, it is called when the session file is saved and the return integer is used to help order the window information in the session file from highest to lowest priority. The default priority is 1. Priority must be lower than any tool which constructs information needed by the java object and higher than any tool which may use information provided by the java object. Some existing tool priorities are
2000 Robert Cannon's catacomb channel builder
1000 cell builder
995 network builder
990 point process manager
100 multiple run fitter
1 linear circuit builder
The priority for the linear circuit builder is a mistake because one could not fit the parameters in a multiple run fitter since that would be created before the linear circuit builder. If the hocSessionSave method exists, it is called when the session file is saved. The argument is the name of the session file. The string returned by this method is copied into the session file just after the hoc statement that constructs the object. The session file name can be used to construct associated file names that save the object data. The return string should use the "ocbox_" objref name to call methods on the newly constructed object. For example, the java interface to Robert Cannon's catacomb channel builder (see nrn-5.1/src/nrnjava/nrnccmb/Channels.java) uses the implementation
        public int hocSessionPriority() {
                return 2000;
        }
        public char[] hocSessionSave(String sfname) {
                StringBuffer s;
                s = new StringBuffer(sfname); s.append(".ccm");
                save(s.toString());
                s = new StringBuffer("{ocbox_.map() ocbox_.load(\"");
                s.append(sfname).append(".ccm\")}\n");
                return s.toString().toCharArray();
        }
When a session file, "temp.ses", is created with a channel builder window then the save("temp.ses.ccm") will be executed to construct a ccm file with all the channel specific information needed for later reconstruction of the object. The session file itself contains the statements
/*Begin catacomb.channel.KSChannel */
{load_java("nrnccmb.Channels", "nrnccmb_Channels")}
ocbox_ = new nrnccmb_Channels()
{ocbox_.map() ocbox_.load("./temp.ses.ccm")}
{PWManager[0].jwindow(ocbox_, 1, 378, 1, 541, 574)}
objref ocbox_
/*End catacomb.channel.KSChannel */
Notice that all the lines were automatically constructed by the internal session save code except for the statement involving ocbox_.load. That information was object specific in regard to its particular policy for constructing the view window for the object and which ccm file to load.