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.
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.
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.
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.
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.
![]() |