Adding server-related collaborative code

The next step is to add the server-specific pieces.

First, we'll add a serviceName which is needed for the client to be able to find the server. As mentioned in the collaboration overview, using the application's class name is a simple way to get a unique service name. Since our simple application is using static methods, that won't work. Instead, we'll just add a static variable to the class file.

We also need to provide a server-specific data initialization method. Since the setupData() method will only be run by the server, we'll rename that to setupServer() (we'll be adding a setupClient() method in the next step). We then add the calls to ClientServer.startServer() and to server.addDisplay() as detailed in the collaboration overview. (Since the sample application doesn't need to reference any data objects, we can skip the server.addDataReferences() step mentioned there.)

Again, verify that the application works after you've finished changing everything.

Here is the sample application with the server-specific changes:
Prev Next
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

import java.io.IOException;
import java.rmi.RemoteException;

import visad.*;
import visad.data.DefaultFamily;
import visad.java2d.DisplayImplJ2D;
import visad.util.ClientServer;

public class DisplayGIF
{
  // location of GIF file to be displayed
  private static final String fileURL = "http://www.ssec.wisc.edu/~billh/billh.gif";

  // name of service (used by collaborative server/client code)
  private static final String serviceName = "CollabGIF";

  private static DisplayImpl setupServer()
    throws IOException, RemoteException, VisADException
  {
    // create a display
    DisplayImpl dpy = new DisplayImplJ2D("display");

    // get the GIF file
    FlatField image = (FlatField )new DefaultFamily("dflt").open(fileURL);

    // compute ScalarMaps from type components
    FunctionType ftype = (FunctionType )image.getType();
    RealTupleType dtype = ftype.getDomain();
    RealTupleType rtype9 = (RealTupleType )ftype.getRange();
    dpy.addMap(new ScalarMap((RealType )dtype.getComponent(0),
                             Display.XAxis));
    dpy.addMap(new ScalarMap((RealType )dtype.getComponent(1),
                             Display.YAxis));
    dpy.addMap(new ScalarMap((RealType )rtype9.getComponent(0),
                             Display.Red));
    dpy.addMap(new ScalarMap((RealType )rtype9.getComponent(1),
                             Display.Green));
    dpy.addMap(new ScalarMap((RealType )rtype9.getComponent(2),
                             Display.Blue));

    // add the GIF data to the display
    DataReferenceImpl ref_image = new DataReferenceImpl("ref_image");
    ref_image.setData(image);
    dpy.addReference(ref_image, null);

    // set up server and add the display to it
    RemoteServerImpl server = ClientServer.startServer(serviceName);
    server.addDisplay(new RemoteDisplayImpl(dpy));

    return dpy;
  }

  private static void setupUI(DisplayImpl dpy)
  {
    // create a frame
    JFrame jframe = new JFrame("GIF");
    jframe.addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent e) { System.exit(0); }
      });

    // add display to frame
    jframe.setContentPane((Container )dpy.getComponent());

    // make frame visible
    jframe.pack();
    jframe.setVisible(true);
  }

  public static void main(String[] args)
    throws IOException, RemoteException, VisADException
  {
    DisplayImpl dpy = setupServer();
    setupUI(dpy);
  }
}
    

Prev Next
Last modified: Wed Jul 12 10:56:46 CDT 2000