ViewModule

All modules that represent user interfaces are subclasses of the ViewModule. Usually developers will subclass UIModule or VisModule, which are both subclasses of ViewModule. The UIModule is subclassed to implement GUIs that solicit user input, and VisModule is subclassed to implement data visualization components.

Visualization modules will generate a visualization when they are done. This visualization can then be saved and can be redisplayed in the D2K system. User interface components are typically used to solicit input from the user, however, they can also be used for visualizations that are not saved, or for status displays.

View Creation and Management

The primary job of the ViewModule is to provide a graphical user interface object, called a user view, which can be displayed by the host platform's graphics subsystem. There is a method that returns a user view. The method looks like this:

  protected UserView createUserView();

This method of the ViewModule is abstract, and must be provided by the subclass. It returns a user interface component called a UserView. This class will be discussed in more detail in the next section. This user view component implements the user interface for the module. This is true of both VisModules and UIModules.

The user view component returned by createUserView() is typically a container of some kind. UserView is an interface, so the class that implements it may be any type of component. These components should never be frames or windows. The window a user interface is placed in can, however, be defined by the module. This gives the module developer more control over the layout of the windows. This also allows user interfaces provided by different modules to share a single frame, and this can make for a more attractive user interface in some cases. Specific information on how to do this is provided in the section on View Embedding.

Execution Management

As already stated, ViewModules are enabled in the same way as other modules. However, they do behave differently once enabled. There is really no notion of ViewModules executing, they don't do any computation. What they do is create user interface components that are then managed by the Java runtime system event management service.

When a ViewModule is enabled, the infrastructure will call its createUserView() method to get a user interface component. This user interface component is then turned over to the Java runtime system to be managed. The user view is then responsible for invoking the methods of the module to update the module's status in response to events that are generated by the graphics subsystem. How the user view deals with these events is addressed in the next section.

There are some methods of the ViewModule that are called by the user view to perform actions or events that will impact the execution of the itinerary. These events are what one would expect -- the passing of data, aborting the itinerary, and dismissing the user view. Here are the definitions of those functions:

  public void viewDone(String command);
  public void viewDone(String command, Object obj);

The viewDone() method is invoked by the user view when it has completed and is ready to be dismissed. The default method will collect the contents of the user view and pass them as outputs (using the field mappings), then dismiss the user interface (the process of collecting results from the user view to be passed is described in the User Views section). This method is occasionally overridden to provide additional functionality. The second form of this function is more often overridden; the additional argument passed is application specific, and is ignored by the superclass. For example, in some cases, it may be useful to create some outputs rather than to have the superclass simply collect and pass the values that the user entered.

There is another method called if the user view wishes the itinerary execution to abort. This method should never be overridden, it may be made final as some point. The method looks like this:

  public void viewAbort();

The viewContinue() method is called if outputs are to be collected and passed without dismissing the user view. After one of these methods is called, the user view remains visible, but the outputs are produced.

  public void viewContinue(String command)
  public void viewContinue(String command, Object obj);

Just like the viewDone() method, viewContinue() has two variations. The second will take an application specific additional input. The UserView implementation can pass anything it wants to this second variation. Typically, this additional object is used to generate the outputs.

These methods are not used by VisModules, as visualizations are actually displayed only after the itinerary is done executing. VisModules don't pass outputs.

Output Mapping

To generate outputs, the infrastructure will need to be able to apply the output mapping returned from the getFieldNameMapping() method to the values associated with the user interface components. The method looks like this:

  protected String[] getFieldNameMapping();

More information on this can be found in a following section. The method of the UserView, compileResults(), is fully responsible for populating a hashtable with the contents of all components that provide output data. It is then the responsibility of the appropriate method, viewDone(), or viewContinue(), to access the elements of the hashtable by name, and pass along the results. These methods will typically call the compileResults() method of their associated UserView (accessed via the getUserView() method). The resulting hashtable will contain the results, which can then be accessed and its contents passed along.

In the discussion of the user interface widgets, you will see how the user interface widgets are named so that the name associated with an output can be obtained by the infrastructure. There are several of these user interface widgets provided in the infrastructure, they are documented in the Widget Implementations section.

If the developer wishes, these methods can be overridden and the field name mappings ignored to produce the outputs in some other way. These methods are provided as a convenience. If these methods are overridden, the superclasses' method should be invoked, as it does some additional bookkeeping.

View Embedding

In some cases, it is useful to be able to allow views associated with different modules to share the same window. This capability is supported by the ViewModule API. Another advantage of this is that you can subclass a ViewModule to change the way a user view is placed in a window without changing the view at all. Only the methods of the module need to be changed -- so you could subclass the module and simply change the methods.

The ViewModule has the ability to return a reference to a Window. When the system determines that a view should be displayed, it will invoke the createWindow() method of the view module:

  public Window createWindow();

If this method returns null, which is the default behavior, the D2K infrastructure will create a window and put the view in the center of that window. However, the module can return a window with one or more embedded pane(s) in it. EmbeddedPane is a very simple subclass of java.awt.Container, which includes a field containing a name. Then when a module produces a user view and the module's getViewName() method returns a string equal to the name stored in the field of the EmbeddedPane, and the getWindowName() method returns the name of the window containing the embedded pane, that view is place inside of that EmbeddedPane. So, we can create a window with one or more EmbeddedPanes, and the appropriate user views will be place in the corresponding containers in the window.

This rather simple mechanism can lead to a variety of behaviors. More than one module can provide the same view name from the getViewName() method, causing one user view to replace another. Alternatively, we can create a window that has panels laid out, even though the views that are to occupy those panels do not yet exist.

The getWindowName() method will return null, or a name for the window. This simple mechanism allows us to assign a title to the window. Or to identify a window that already exists.