NOTICE: This version of the NSF Unidata web site (archive.unidata.ucar.edu) is no longer being updated.
Current content can be found at unidata.ucar.edu.
To learn about what's going on, see About the Archive Site.
VisAD works quite nicely in an applet. Most of the programming is straightforward, with one required trick/work-around. I'll describe in this email the techniques I employed, in case anybody else should need to run VisAD in an environment similar to mine. First off, here's a summary of the tasks which must be completed to run VisAD in an applet: 1) Load the Sun JRE plug-in on your machine, and convert any html to make it call the plug-in. 2) Load Java3d on your client machine, setting environmental variables as needed. 3) Write a Java program that calls VisAD and which can run as an applet. 4) Make your html page spawn a new browser window, and send all VisAD commands to that window. The first 2 steps come right out of the documentation. The 3rd step is implied by the question, but deserves a couple notes: 1) I subclassed from JApplet, though I'll bet that the AWT form would work too, and 2) note that the VisAD library only gets loaded once across all applet instances (at least under IE 5.00) so you'll probably want to initialize variables the first time through only, and also to make a few variables constant to simplify subsequent invocations. The 4th step is the work around I found to get around a nasty garbage collection problem for which I couldn't find a more elegant solution. This problem first showed up when I tried to create my second VisAD plot within a single browser session (the first was easy enough). To describe the issue more completely, I quote from my earlier post: >Under IE 5.0, using the Java plug-in 1.3, the JVM loads my applet and >visad.jar the first time they're needed. The next time around, the browser >calls Class.newInstance() (which performs a shallow copy) to generate a new >version of my applet class, while keeping the instantiations of any classes ... > ... Now the trouble starts. That first instance of my class is >gone for good, so the garbage collector can start picking it to pieces, and >since there are no explicit references to the information stored in VisAD's >namespace, I think that the memory VisAD has allocated starts to be picked >apart as well. The classloader doesn't bother to reload visad.jar from >scratch, since it knows that it loaded visad.jar once already, and assumes >that I've kept explicit pointers to any memory I want saved. I still agree with this description. No matter which variables I held static, my browser would crash soon after I tried my second plot, as long as the new plot went into a new window. My work-around was to send all the graphics to one window. Spawning this window and writing to it repeatedly can be accomplished with a few lines of Javascipt: <SCRIPT LANGUGE="JavaScript"> { var myw window.open("","OneVisadWin","status=no,location=no,menu=no"); myw.document.write("..."); } </SCRIPT> The first line of code creates a new window, or gets a pointer to a window of the given name if one already exists. The next line (and others that must follow it) should contain code to launch your applet and send it any parameters you like. As long as your VisAD applet is launched within this window you can repeatedly call VisAD routines, and everything ought to go swimmingly. As to why this work-around is necessary, I return to my previous post: >Note: I think this IS NOT a VisAD bug (I'd call it instead a browser and/or >Java plug-in bug). There may, however, be aspects of VisAD that would >allow me to get around the problem. If, for example, I could get a pointer >to the root of the data structure that VisAD uses internally, then I could >set a static variable within my program to point to it, and everything would >be protected from the GC, and I could use the variables I created the first >time through. ... This is roughly the approach that the work-around takes, though I was a little confused about the way in which the JVM garbage collector treats static variables. The key to a working solution is that the Frame the applet uses must reference a VisAD variable, and the frame must never be unloaded. Specifically, I use the DisplayImpl.getComponent(), and add it to a JPanel, which I then add to the applet frame. As further evidence that my proposed explanation is correct, I encountered the following situation: I wanted two VisAD displays, one for 2-d and one for 3-d. If I created them the first time I hit the applet, and stored them in static variables, to add and remove from panels as I needed, my applet quickly crashed. If instead I put both displays on a panel and left them there, making one or the other current as needed using the following two calls (as an example, I make the 2-d display current): panel3d.setSize(1,1); panel2d.setSize(480,480); then the program worked quite reliably. That's all for now. I'll try to work up a minimal 'hello visad-applet world' example sometime soon. Thanks to everyone on the list who responded to my queries, namely Dave Glowacki, Ng Sag Teong, and TomW. Thanks also to a few people who responded to me offline. If anyone else tries this approach then please let me know if it worked for you. Thanks. Ben
visad
archives: