a visad app/applet that behaves in ways I don't understand

Hello VisAD list;

Since this is my first post to this list let me, before I begin describing
my troubles, state that I think
Vis-AD is a really impressive effort.  I greatly appreciate those who have
put their thought and work
into this project to make it do what it does, and I look forward to
utilizing it.  Now, as to the reasons
behind this post...

We have a program that generates data, and we want to be able to plot the
results from within a
browser.  For the purposes of this example, assume that we need to create
only 3-d scatter plots.
I loaded Java-3d onto my client box, brought down the visad jar file, wrote
a short applet, and within 
a few hours time visad was running in my browser like a champ (in fact, my
plots rotate more quickly 
on my Dell XPS450 under the browser than they do on my SGI O2-- go figure).
My problems started 
when I tried to replicate a user's typical use of our program (i.e. generate
data, plot data, repeat).  My 
applet works beautifully the first time, but won't show any plots on
subsequent invocations.  To investigate
this behavior, I modified my program so that it could also run as an app.

The app also produced nice plots at first, but if I arranged the calls in a
particular way I could get 
it to apparently act in about the same way as the applet.  The source I
include below creates the
problem, but can be fixed in a number of ways (see the bottom of the source
for the following references):
1) comment out "test line 1"; 2) un-comment test lines 2-4; or 3) comment
out test lines 5 and 6.
Any of these methods allows for a nice display at the end of the program,
but I don't have an explanation
as to why.  It may be that the app's troubles are completely unrelated to
those of the applet-- I don't know.
I'm including this information for 2 reasons; because it allows us to rule
out certain explanations of why
the applet hangs, and because perhaps it may offer some clue to somebody
more knowledgeable than 
myself about what's going wrong.

One additional note: the app _sometimes_ works correctly without any
modification (suggesting a
timing problem?).  I have never seen the applet generate a second plot,

To summarize:  my applet only draws a nice picture the first time I use it--
after that, I must start a new
browser session in order to see another plot.  The app also shows a problem,
which is easily fixed, but
which might pertain to the applet problem.  I'm quite new to VisAD, so
please freely criticize the way
in which I'm using the package.  For that matter I've only been using Java
for 6 months, so you can criticize
my Java programming too, if you like.  If anybody is having trouble getting
visad to run as an applet then 
email me, and I can at least tell you what I did to get you started.  Also,
if anybody else is using VisAD 
from an applet, I'd be happy to talk to you and swap experiences.  Thanks in
advance for any help,


source begins below this line.  I apologize for the length, but at least it
provides a full working (?) example.
import visad.*;
import visad.util.*;
import visad.browser.*;
import visad.java2d.DisplayImplJ2D;
import visad.java3d.DisplayImplJ3D;
import java.rmi.RemoteException;
import java.math.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.lang.Float;
import java.applet.*;
import javax.swing.*;

// The troublesome class, which produces a 3-d scatter plot.  The code
//  runs without modification as either an applet or app.  
public class apfrm extends Applet
  static RealType x1, x2, x3, index;
  static RealTupleType x1_x2_x3_tuple;
  static DisplayImpl display = null;
  static ScalarMap x1Map, x2Map, x3Map;
  static ConstantMap[] pointsCMap = null;
  static RangeWidget ranWid = null;
  static DataReferenceImpl data_ref = null;
  static FlatField vals_ff=null;    
  static Integer1DSet prop_set=null;
  static FunctionType func_i_tuple=null;
  // a couple useful variables
  static Boolean firsttime = Boolean.TRUE;
  static int runcnt = 0;
  // next 2 needed to run as an app
  static boolean inApplet = true;
  static Hashtable parameters = new Hashtable();

// An applet hits this routine first.  Note that I had to include my own
//  'one time only' flag, since newer versions of IE want to run the
//  init program each time through, instead of only once per each applet.
public void init ()
    System.out.println("entering init");
        if ( firsttime.booleanValue() )
            System.out.println("first time");
            firsttime = Boolean.FALSE;
            catch (Exception e)
          System.out.println("not first time");
    System.out.println("leaving init");

//  IE silliness-- otherwise these calls would be in init()
private void multiinit_workaround() throws Exception
    // visad variables 
    x1 = new RealType( "x-axis" );
    x2 = new RealType( "y-axis" );
    x3 = new RealType( "z-axis" );
    x1_x2_x3_tuple = new RealTupleType(x1, x2, x3);
    x1Map = new ScalarMap( x1, Display.XAxis );
    x2Map = new ScalarMap( x2, Display.YAxis );
    x3Map = new ScalarMap( x3, Display.ZAxis );
    pointsCMap = new ConstantMap[4];    
    pointsCMap[0] = new ConstantMap( 1.0f, Display.Red );
    pointsCMap[1] = new ConstantMap( 0.0f, Display.Green );
    pointsCMap[2] = new ConstantMap( 0.0f, Display.Blue );
    pointsCMap[3] = new ConstantMap( 4.5f, Display.PointSize );
    data_ref = new DataReferenceImpl("data_ref");
    display = new DisplayImplJ3D("display");

// most interesting work goes on here
public void start()
    boolean problems = false;
    Panel panel = null;

    System.out.println("entering start");


    // get the data
    Vector d1 = getdim("d1_");
    Vector d2 = getdim("d2_");
    Vector d3 = getdim("d3_");

    // make a new index for the data, since it may have a different length
    if ( !problems )
            // reinitialize these variables each time through
            index = new RealType("index"+runcnt); 
            prop_set = new Integer1DSet( index, d1.size() );  
            func_i_tuple = new FunctionType( index, x1_x2_x3_tuple );

            vals_ff = new FlatField( func_i_tuple, prop_set);
        catch (Exception e)
            System.out.println("apfrm::start.ERROR:  Common code section
            problems = true;

    // The time through we add the maps, while every subsequent time we
    //  the maps, modify them, and them put them back.
    if ( !problems )
            if (runcnt > 1)
              { // We have old data to deal with

                // this part stolen from Bill Hubbard's ex. in the mailing
list archive, dated Feb. 25, '00

                // save the old maps
                Vector sMaps = display.getMapVector();
                Vector cMaps = display.getConstantMapVector();
                // remove links to data
                // clear ScalarMaps

                // add selected maps back to display
                if (sMaps != null) {
                  int len = sMaps.size();
                  for (int i = 0; i < len; i++) {
                    ScalarMap map = (ScalarMap )sMaps.elementAt(i);

                // add ConstantMaps back
                if (cMaps != null) {
                  int len = cMaps.size();
                  for (int i = 0; i < len; i++) {
                    ConstantMap map = (ConstantMap )cMaps.elementAt(i);
                    System.out.println("System map added.");

              { // first time through

                display.addMap( x1Map );
                display.addMap( x2Map );
                display.addMap( x3Map );
            problems = add3dData( d1, d2, d3, 
                                  "z" );
            display.addReference( data_ref, pointsCMap );

        catch (Exception e)
            System.out.println("apfrm::start.ERROR:  Common code II section
            problems = true;

    if ( !problems )

        // add display to Panel
        panel = new Panel();
        panel.setLayout( new BoxLayout( panel, BoxLayout.Y_AXIS ) );
        panel.setLocation( 0,0 );
        panel.add( display.getComponent() );
        // clear everything out and start again
        this.removeAll();  // unnecessary in an applet, I think
        this.setLayout ( new BorderLayout() );
        this.setSize( 450, 450 );
        this.add( "Center", panel );    
        this.setVisible( true );

    System.out.println("leaving start");


  // put the data into a form that visad can access
private boolean add3dData(Vector d1, Vector d2, Vector d3, 
                       String xname, String yname, String zname )
    int dimension=3;
    float[][] point_vals = null;
    boolean problems = false;

        point_vals = new float[dimension][];
        for ( int i = 0; i < dimension; i++ )
            point_vals[i] = new float[ d1.size() ];
            for ( int j = 0; j < d1.size(); j++ )
                if ( i == 0 )
                  point_vals[i][j] = Float.valueOf( (String) d1.elementAt(j)
                else if ( i == 1 )
                  point_vals[i][j] = Float.valueOf( (String) d2.elementAt(j)
                else if ( i == 2 )
                  point_vals[i][j] = Float.valueOf( (String) d3.elementAt(j)
    catch ( NumberFormatException nfe )
        problems = true;
        System.out.println("apfrm::add3dData.ERROR:  3-d plot.  Problem with
conversion to float data.");
        x1Map.setScalarName( xname );
        x2Map.setScalarName( yname );
        x3Map.setScalarName( zname );   

        vals_ff.setSamples( point_vals ); 
        data_ref.setData( vals_ff );                
    catch ( Exception e )
        problems = true;
        System.out.println("apfrm::add3dData.ERROR:  3-d plot.  Add data/set
name problem.");
        showStatus( new String( e.getMessage() ) );

    return problems;

//  Get all data for a dimension
private Vector getdim( String suffix )
  Vector tv = new Vector();
  String tmp = null;
  int tcnt = 0;
  if ( inApplet )
      while ( ( tmp = getParameter( suffix+tcnt ) ) != null )
          tv.add( new String(tmp) );
      while ( ( tmp = (String) parameters.get( suffix+tcnt ) ) != null )
          tv.add( new String(tmp) );

  return tv;

  // observe when everything gets hit in an applet 
public void close()
    System.out.println("entering/leaving close");

  // observe when everything gets hit in an applet 
public void stop()
    System.out.println("entering/leaving stop");

  // observe when everything gets hit in an applet 
public void paint()
    System.out.println("entering/leaving paint");

// run as an app
public static void main(String args[])
  inApplet = false;

  Frame appfrm = new Frame("apfrm as app");

  apfrm app = new apfrm();

  appfrm.add( "Center", app );

  // load parms fake parms, since we're running as an app, not an applet



  // now things get interesting...

  appfrm.show();                // test line 1

  try{                          // test line 2
    Thread.sleep(5000);         // test line 3
  }catch (Exception e){}        // test line 4

  app.init();                   // test line 5
  app.start();                  // test line 6