Collaborative VisAD applications.

VisAD applications can run in any of three networked modes: standalone, server or client.

Standalone mode is the ordinary non-networked application mode.

Server mode is almost identical to standalone mode, with a few exceptions. Once the data setup is complete, the application listens for (and responds to) clients in the background and otherwise operates in exactly the same manner as a standalone application.

In client mode, the application connects to the server application and has it send the information necessary to construct copies of any (or all) of the server's Displays. Once that is done, the server and client remain connected and forward any significant changes to each other, so that the Display(s) remain synchronized.

A client's Display information comes from the server. All data for the copied Display comes from the server as well, so if the server application is terminated, the client's Display will no longer work.

Refactoring an application for collaboration

A typical VisAD application initializes some data objects (Displays, ScalarMaps, RealTypes, FlatFields, etc), associates them with some user interface elements (a JFrame containing the Display component, some widgets from visad.util, possibly a locally developed widget or two), packs everything in a window and pops it up on the user's screen.

To add collaboration to a VisAD application like this (or to build a simple collaborative application), the initialization code should be separated into one or more data setup methods and one or more user interface setup methods, and called in that order (data setup then UI setup).

This isn't an absolute necessity, but it simplifies things for code-reuse purposes, because the client needs to build its own copy of the user interface widgets (so it needs to run the UI setup method(s)) but it will be using the server's data (and thus does not need to run the data setup method(s).)

Also make sure that user interface setup methods don't depend upon the data initialization methods setting class-wide variables. Instead, user interface methods should fetch the Controls they need via the DisplayImpl getControl() methods, any ScalarMaps via the getMapVector() method, and any ConstantMaps via the getConstantMapVector() method.

Making an application collaborative

After you have the standalone application working, make the following changes:
  1. Choose a "service name", which is the name used to look up the server's information. I typically use the application's class name:
    String serviceName = getClass().getName();
    but any string will do, provided it is not used by multiple applications (or multiple instances of the same application) on a single machine. If you want to run multiple instances of an application on a single machine, you'll need to have the user specify the service name somehow.
  2. Optionally add some way to start the application up in standalone, server and client modes. This is often done with a special argument in the String argument list passed to the application's main() method, but it could also be indicated through a property or even via a UI widget.
  3. For standalone/server mode, call the data setup method to create the Display(s) and any data references.
  4. For server mode:
  5. For client mode:
  6. For all modes, call the user interface setup method

    This is greatly simplified if you use the DisplayImpl.getWidgetPanel() method, which automatically builds controls for the Display's ScalarMaps.
  7. Verify that all collaborative user interface widgets are based on either Controls or ScalarMaps (this is already true of all the widgets in the visad.util package). This means that, as well as changing some aspect of the display due to user input (via the itemStateChanged() method), a collaborative widget must also change its visible state based on Control or ScalarMap changes (as a ControlListener via the controlChanged() method, or as a ScalarMapListener via the mapChanged() method.)

    For instance, a standalone version of a widget to turn the VisAD box on and off might be implemented as a JCheckBox widget with an ItemListener which calls display.getDisplayRenderer().setBoxOn() with the appropriate value (true or false) A collaborative version needs to also listen to the RendererControl (which holds the state of several DisplayRenderer values) and reflect box visibility changes in RendererControl by changing the state of the UI widget (adding a checkmark when the box is turned on, removing a checkmark when the box is turned off.)
For more details, you can read a walkthrough of the conversion process.

Testing your collaborative application

Once you've converted your application, verify that it still runs in standalone mode.

After confirming that standalone mode continues to work, try running the application as a server. This shouldn't break anything, since you've simply adding a few steps which should have no effect on the operation of your application.

When you have your application running as a server, try starting another copy of your application as a client. This is the point where a number of problems can be revealed:

Some things to consider

To simplify things, keep the following points in mind when designing a VisAD application:

If you have any questions join the VisAD mailing list (see the VisAD web page for instructions) and then send your questions
Last modified: Tue Jul 11 14:59:42 CDT 2000