<?xml version='1.0'?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" 
               "http://docbook.org/xml/4.2/docbookx.dtd"
	       [
	       <!ENTITY copyright SYSTEM "copyright.xml">
	       ]>

<chapter title="User Interfaces for Jini Services" id="19">
<title id="User Interfaces for Jini Services">
User Interfaces for Jini Services
</title>

<tocchap>
<title>
Contents
</title>

<toclevel1>
<tocentry>
  <ulink url="#User Interfaces as Entries">
    User Interfaces as Entries
  </ulink>
</tocentry>
<tocentry>
  <ulink url="#User Interfaces from Factory Objects">
    User Interfaces from Factory Objects
  </ulink>
</tocentry>
<tocentry>
  <ulink url="#Current Factories">
    Current Factories
  </ulink>
</tocentry>
<tocentry>
  <ulink url="#Marshalling Factories">
    Marshalling Factories
  </ulink>
</tocentry>
<tocentry>
  <ulink url="#UIDescriptor">
    UIDescriptor
  </ulink>
</tocentry>
<tocentry>
  <ulink url="#Toolkit">
    Toolkit
  </ulink>
</tocentry>
<tocentry>
  <ulink url="#File Classifier Example">
    File Classifier Example
  </ulink>
</tocentry>
<tocentry>
  <ulink url="#Support Classes">
    Support Classes
  </ulink>
</tocentry>
<tocentry>
  <ulink url="#Images">
    Images
  </ulink>
</tocentry>
<tocentry>
  <ulink url="#ServiceType">
    ServiceType
  </ulink>
</tocentry>

<!--
<tocentry>
  <ulink url="#MindStorms">
    MindStorms
  </ulink>
  <toclevel2>
    <tocentry>
      <ulink url="#RCXLoaderFrame">
        RCXLoaderFrame
      </ulink>
    </tocentry>
    <tocentry>
      <ulink url="#RCXLoaderFrameFactory">
        RCXLoaderFrameFactory
      </ulink>
    </tocentry>
    <tocentry>
      <ulink url="#Exporting the RCXLoaderFrameFactory">
        Exporting the RCXLoaderFrameFactory
      </ulink>
    </tocentry>
    <tocentry>
      <ulink url="#Customised User Interfaces">
        Customised User Interfaces
      </ulink>
    </tocentry>
    <tocentry>
      <ulink url="#CarJFrame">
        CarJFrame
      </ulink>
    </tocentry>
    <tocentry>
      <ulink url="#CarJFrameFactory">
        CarJFrameFactory
      </ulink>
    </tocentry>
    <tocentry>
      <ulink url="#Exporting the CarJFrameFactory">
        Exporting the CarJFrameFactory
      </ulink>
    </tocentry>
    <tocentry>
      <ulink url="#The RCX Client">
        The RCX Client
      </ulink>
    </tocentry>
  </toclevel2>                                                                  
</tocentry>
-->

<tocentry>
  <ulink url="#Summary">
    Summary
  </ulink>
</tocentry>

</toclevel1>
</tocchap>

<abstract>
<para>

</para>
</abstract>

<sect1>
<title id="User Interfaces as Entries">
User Interfaces as Entries
</title>

<para>
Interaction with a service is specified by its interface. This will be
the same across all implementations of the interface. This doesn't
allow any flexibility in using the service since a client will only know about
the methods defined in the interface. The interface is the defining level
for using this type of service. But services can be implemented in many
different ways, and service implementations do in fact differ.
There is a need to allow for this. The mechanism used in Jini is
to put these differences in <code>Entry</code> objects. Typical objects
supplied by vendors may include <code>Name</code> and <code>ServiceInfo</code>.
</para>

<para>
Clients can make use of the interface and these additional entry items,
primarily in the selection of a service. But once they have the service,
are they just constrained to use it via the type interface? 
The type interface is designed to allow a client application to use
the service, in a programmatic way by calling methods.
However, many services
could probably benefit from some sort of user interface. For example, a
printer may supply a method to print a file, but it may have the capability
to print multiple copies of the same file. Rather than relying on the client
to be smart enough to figure this out, the printer vendor may want to 
call attention to this by supplying a user-interface object with a special
component for ``number of copies''.
</para>

<para>
The user interface for a service cannot expect to have all details supplied
by the client - at best a client could only manage a fairly generic user interface.
It should come from the vendor, or maybe even third parties. When your video
player becomes Jini enabled, it would be a godsend for 
<emphasis>someone</emphasis> to supply a decent user interface for it,
since the video player vendors seem generally incapable of doing so!
The <code>Entry</code> objects are not just restricted to
providing static data - as Java
objects they are perfectly capable of running as user-interface objects.
</para>

</sect1>

<sect1>
<title id="User Interfaces from Factory Objects">
User Interfaces from Factory Objects
</title>

<para>
In the chapter on ``More Complex Examples'' some discussion was given to
the location of code, using user-interface components as examples. The
chapter suggested that user interfaces should not be created on the server
side but on the client side. So the user-interface should be exported
as a <emphasis>factory</emphasis> object that can create the user-interface
on the client side.
</para>

<para>
More arguments can be given to support this:
<orderedlist>
<listitem>
  A service exported from a low resource computer, such as an embedded Java
  engine may not have the classes on the service side needed to create the
  user-interface (it may not have the Swing or even the AWT libraries)
</listitem>
<listitem>
  There may be many potential user-interfaces for any particular service:
  the Palm Pilot (with small grey-scale screen) requires a different
  interface to a high-end workstation with huge screen and enormous
  numbers of colours. It is not reasonable to expect the service to create 
  every one of these, but it could export factories capable of doing so
</listitem>
<listitem>
  Localisation of internationalised services cannot be done on the service
  side, only on the client side
</listitem>
</orderedlist>
</para>

<para>
The service should export zero or more user-interface <emphasis>factories</emphasis>,
with methods to create the interface, such as <code>getJFrame()</code>. 
The service and its user-interface
factory entry will both be retrieved by the client. The client will then
create the user-interface. Note that the factory will not know the service
object beforehand - if it was given one during <emphasis>its</emphasis> construction
(on the service side) it would end up with a <emphasis>service</emphasis>-side 
copy of the service instead of a <emphasis>client</emphasis>-side copy! 
So when it is asked for a
user-interface (on the client side), it should be passed the service as well in
a parameter to user-interface creation. 
In fact, it should probably be passed all of the information about the service,
as retrieved in the <code>ServiceItem</code> obtained from a lookup service.
</para>

<para>
A typical factory is the one that returns a <code>JFrame</code>. This is defined
as
<programlisting>
package net.jini.lookup.ui.factory;

import javax.swing.JFrame;

public interface JFrameFactory {
    String TOOLKIT = "javax.swing";
    String TYPE_NAME = "net.jini.lookup.ui.factory.JFrameFactory";

    JFrame getJFrame(Object roleObject);
}
</programlisting>
The factory imports the minimum number of classes 
for the interface to compile and be exported.
An implementation of this interface will probably use many more. The <code>roleObject</code>
passes in any necessary information to the UI constructor. This is usually the
<code>ServiceItem</code>, as this contains all the information (including the service)
that was retrieved from a lookup service. The factory can then create a UI that acts as
an interface to the service, and can use any additional information in the
<code>ServiceItem</code> such as entries for <code>ServiceInfo</code>
or <code>ServiceType</code> which could be
shown, say, in an ``about'' box.
</para>

<para>
A factory that returns a visual component such as this should not make the component
visible. This will allow its size and placement to be set before showing it.
Similarly, a ``playable'' UI such as an audio file, should not be in a ``playing''
state.
</para>

</sect1>

<sect1>

<title id="Current Factories">
Current Factories
</title>
<para>
A service may supply lots of these factories, each capable of creating a
different user interface object. This is to allow for the differing capabilities
of ``viewing'' devices, or even for different user preferences. One user may
always like a Web-style interface, another may be content with an AWT interface,
a third may want the accessibility mechanisms possible with a Swing interface, and
so on.
</para>

<para>
The set of factories currently includes
<orderedlist>
<listitem>
  <code>DialogFactory</code> which returns an instance of <code>java.awt.Dialog</code>
  (or one of its subclasses)  which depends on the AWT but not Swing
</listitem>
<listitem>
  <code>FrameFactory</code> which returns an instance of <code>java.awt.Frame</code>
  (or one of its subclasses)  which depends on the AWT but not Swing
</listitem>
<listitem>
  <code>JComponentFactory</code> which returns an instance of <code>javax.swing.JComponent</code>
  (or one of its subclasses such as a <code>JList</code>)
</listitem>
<listitem>
  <code>JDialogFactory</code> which returns an instance of <code>javax.swing.JDialog</code>
  (or one of its subclasses)
</listitem>
<listitem>
  <code>JFrameFactory</code> which returns an instance of <code>javax.swing.JFrame</code>
  (or one of its subclasses)
</listitem>
<listitem>
  <code>JWindowFactory</code> which returns an instance of <code>javax.swing.JWindow</code>
  (or one of its subclasses)
</listitem>
<listitem>
  <code>PanelFactory</code> which returns an instance of <code>java.awt.Panel</code>
  (or one of its subclasses) which depends on the AWT but not Swing
</listitem>
<listitem>
  <code>WindowFactory</code> which returns an instance of <code>java.awt.Window</code>
  (or one of its subclasses) which depends on the AWT but not Swing
</listitem>
</orderedlist>
These can be extended by any user, but to allow wide understanding of these factories
any new factories should be approved by the Jini Community.
</para>

<para>
These factories are all defined as interfaces. An implementation will define a
<code>getXXX()</code> method that will return a user interface object.
The current set of factories returns objects that belong to the Swing or AWT classes.
Factories added in later iterations of the specification may return objects belonging
to other user interface styles, such as speech objects. Although an interface
may specify that a method such as <code>getJFrame()</code> will return a
<code>JFrame</code>, an implementation will in fact return a subclass of this,
which also implements a <emphasis>role</emphasis> interface.
</para>

<!--
<para>
For UI's that use a web-like interface such as HTML, XML or WML, I have suggested 
a set of URL factories which will return a URL that can be displayed on the
client side by a suitable viewer (e.g. for HTML the <code>JEditorPane</code>
can be used)
<orderedlist>
<listitem>
  <code>URLFactory</code> which returns a URL with no particular protocol or
  content type (e.g. it could be an ftp URL)
</listitem>
<listitem>
  <code>HTMLFactory</code> which returns a URL with HTTP protocol and HTML content
</listitem>
<listitem>
  <code>XMLFactory</code> which returns a URL with HTTP protocol and XML content
</listitem>
<listitem>
  <code>WMLFactory</code> which returns a URL with HTTP protocol and WML
  (Wireless Markup Language) content
</listitem>
</orderedlist>
Such user interfaces will most likely become the norm on portable phones and
PDAs (portable digital assistants). These factories are not part of the 
proposed specification and are discussed separately in a later section.

</para>
-->

</sect1>

<sect1>
<title id="Marshalling Factories"> 
Marshalling Factories
</title>

<para>
There may be many factories for a service, and each of them will generate a different
user interface. These factories and their user interfaces will be different for
each service. The standard factory <emphasis>interfaces</emphasis> 
will probably be known to both
clients and services, but the actual <emphasis>implementations</emphasis> 
of these will only be known
to services (or maybe to third-party vendors who add a user interface to a service).
</para>

<para>
If a client receives a <code>ServiceItem</code> containing entries with many
factory implementation objects, it will need to download the class files for all of these,
as it instantiates the entry objects. There is a strong chance that each factory
may be bundled into a <code>jar</code> file that also contains the user interface
objects themselves. So if the entries directly 
contain the factories, then the client will need
to download a set of class files, before it even goes about the business of
deciding which of the possible user interfaces it wants to select.
</para>

<para>
This downloading may take time on a slow connection, such as wireless or home
network link. It may also cost memory which may be scarce in small devices such
as PDA's. So it is advantageous to hide the actual factory classes until the
client has decided that it does in fact want a particular class. Then, of course,
it will have to download all of the class files needed by that factory.
</para>

<para>
In order to hide the factories, they are wrapped in a <code>MarshalledObject</code>.
This keeps a representation of the factory, and also a reference to its codebase,
so that when it is unwrapped the necessary classes can be located and downloaded.
By putting it into entries in this form, no attempt is made to download its classes
until it is unmarshalled.
</para>

<para>
The <emphasis>decision</emphasis> as to whether or not to unmarshall a class
can be made on a <emphasis>separate</emphasis> piece of information, such as
a set of <code>String</code>'s which hold the names of the factory class
(and all of its superclasses and interfaces). This level of indirection
is a bit of a nuisance, but not too bad:
<programlisting>
if (typeNames.contains("net.jini.lookup.ui.factory.JFrameFactory") {
    factory = (JFrameFactory) marshalledObject.get();
    ....
} 
</programlisting>
A client that does not want to use a <code>JFrameFactory</code> will just not
perform this test, unmarshalling or attempted coercion. This does place a responsibility
on service-side programmers to ensure this coercion will be correct. In effect, this is a
manoeuvre to circumvent the type-safe model of Java purely for optimisation purposes.
</para>

<para>
There is one final wrinkle on loading the class files for a factory: a running JVM
may have many class loaders. When loading the files for a factory, you want to make
sure that the class loader is one that will actually download the class files
across the network as required. The class loader associated with the service itself
will be the most appropriate for this.
</para>
</sect1>

<sect1>
<title id="UIDEscriptor">
UIDescriptor
</title>
<para>
An entry for a factory must contain the factory itself hidden in a <code>MarshalledObject</code>
and some string representation of the factory's class(es). It may need other descriptive
information about the factory. The <code>UIDescriptor</code> captures all this
<programlisting>
package net.jini.lookup.entry;

public class UIDescriptor extends AbstractEntry {

    public String role;
    public String toolkit;
    public Set attributes;
    public MarshalledObject factory;

    public UIDescriptor();
    public UIDescriptor(String role, String toolkit, 
                        Set attributes, MarshalledObject factory);

    public final Object getUIFactory(ClassLoader parentLoader)
           throws IOException, ClassNotFoundException;
}
</programlisting>
</para>

<para>
There are several features in the <code>UIDescriptor</code> that we haven't mentioned
yet, and the factory's type appears to be missing (it is one of the <code>attributes</code>).
</para>

<sect2>
<title id="Toolkit">
Toolkit
</title>

<para>
A user interface will typically require a particular package to be present or it will
just not function. For example, a factory that creates a <code>JFrame</code> will
require the <code>javax.swing</code> package. This can provide a quick filter on
whether or not to accept a factory: if it is based on a package the client doesn't have,
then it can just reject this factory.
</para>

<para>
This isn't a bullet-proof means of selection.
For example, the Java Media Framework is a fixed-size package designed to handle lots
of different media types. So if your user interface is a Quicktime movie, then you 
might specify the JMF package. However, the media types it handles are not fixed,
and can depend on native code libraries. For example, the current Solaris version
of the JMF package has a native code library to handle MPEG movies, which is not
present in the Linux version. So having the package specified by the 
<code>toolkit</code> does not <emphasis>guarantee</emphasis> that
the class files for this user interface will be present.
It is primarily intended for narrowing lookups based on the UIs offered.
</para>

</sect2>

<sect2>
<title id="Role">
Role
</title>
</sect2>

<para>
There are many possible roles for a user-interface. 
The <code>role</code>
is intended to cover this. This is specified as an interface, with one field
<code>role</code>, which is the fully qualified path name of the interface. There are
currently three interfaces:
<orderedlist>
<listitem>
 The <code>net.jini.lookup.ui.MainUI</code> role. This role is
 for the standard user interface used by ordinary clients of the service
<programlisting>
package net.jini.lookup.ui;
public interface MainUI {
    String ROLE = "net.jini.lookup.ui.MainUI";
}                                                                               
</programlisting>
</listitem>
<listitem>
  The role <code>net.jini.lookup.ui.AdminUI</code>
  is for use by the service's administrator
<programlisting>
package net.jini.lookup.ui;
public interface AdminUI {
    String ROLE = "net.jini.lookup.ui.AdminUI";
}                                                                               
</programlisting>
</listitem>
<listitem>
  <code>net.jini.lookup.ui.AboutUI</code>
  for information about the service, which is presentable by a user interface object
<programlisting>
package net.jini.lookup.ui;
public interface AboutUI {
    String ROLE = "net.jini.lookup.ui.AboutUI";
}                                                                               
</programlisting>

</listitem>
</orderedlist>
</para>


<para>
A service will specify a role for each of the user interfaces it supplies.
This role is given in a number of ways for different objects
<orderedlist>
<listitem>
The <code>role</code> field in the <code>UIDescriptor</code> must be set
to the string <code>ROLE</code> of the role interface
</listitem>
<listitem>
The user interface indicates that it acts a role by
implementing the particular role specified. 
</listitem>
<listitem>
The factory does not explicitly know about the role, but the factory contained
in a <code>UIDescriptor</code> must produce a user interface implementing
the role.
</listitem>
</orderedlist>
The service must ensure that the <code>UIDescriptors</code> it produces
follows these rules. How it actually does so is not specified. There are several
possibilities, such as
<orderedlist>
<listitem>
  When a factory is created, the role is passed in through a constructor.
  It can then use this role to cast the <code>roleObject</code> in the
  <code>getXXX()</code> method to the expected class (currently this is always
  a <code>ServiceItem</code>).
</listitem>
<listitem>
  There could be different factories for different roles, and the 
  <code>UIDescriptor</code> should have the right factory for that role
</listitem>
</orderedlist>
The factory could perform some ``sanity'' checking if desired: since all
<code>roleObject</code>'s are (presently) the service items, it could search through
these for the <code>UIDescriptor</code>, and then check that it's
<code>role</code> matches what the factory expects.
</para>

<para>
There has been much discussion about ``flavours'' to roles, such as an ``expert'' role,
or a ``learner'' role. This has been deferred as too complicated, 
at least for the first version  of the specification.
</para>
<sect2>
<title id="Attributes">
Attributes
</title>

<para>
The <code>attributes</code> section of a <code>UIDescriptor</code> can carry any
other information about the user interface object that is deemed useful.
Currently this includes
<orderedlist>
<listitem>
<para>
  A <code>UIFactoryTypes</code> which contains
  a set of <code>String</code>'s. This contains the
  strings for the fully qualified class names of the factory this entry contains.
  The current factory hierarchy is very shallow so this may be just a singleton set, such as 
  {<code>JFrameFactory.TYPE_NAME</code>}.
</para>

<para>
  There is an unfortunate wrinkle with Java sets and Jini entries: the lookup
  matching mechanism for entries tests byte equality of serialised forms, and most
  implementations of the <code>Set</code> interface are not constant across all
  Java virtual machines. So instead of common set types such as <code>HashSet</code>
  you should use special types such as <code>com.artima.lookup.util.ConsistentSet</code>
  This has a constructor which takes a <code>Set</code> in its constructor.
  This makes slightly messy code a bit more messy:

<programlisting>
        Set attribs = new HashSet();
        Set typeNames = new HashSet();
        typeNames.add(JFrameFactory.TYPE_NAME);
        typeNames = new ConsistentSet(typeNames);
        attribs.add(new UIFactoryTypes(typeNames));
        attribs = new ConsistentSet(attribs);                             
</programlisting>
  Note that a client is not usually interested in the actual type of the factory, but
  rather of the interface it implements. This is just like Jini services themselves,
  where we only need to know the methods that can be called, and are not concerned
  with the implementation details.
</para> 
</listitem>
<listitem>
  An <code>AccessibleUI</code> object. Inclusion of this is a statement that the
  user interface implements <code>javax.accessibility.Accessible</code> and that
  the user interface would work well with assistive technologies
</listitem>
<listitem>
  A <code>Locales</code> object which specifies the locales supported by the
  user interface
</listitem>
<listitem>
  A <code>RequiredPackages</code> object which contains information about all
  of the packages that the user interface needs to run. This is not a guarantee
  that the user interface will actually run, nor a guarantee that it will be
  a usable interface! But it may help a client decide whether or not to use
  a particular user interface
</listitem>

</orderedlist>
</para>

</sect2>

</sect1>

<sect1>
<title id="File Classifier Example">
File Classifier Example
</title>

<para>
The file classifier has been used throughout as a simple example of a service, 
to illustrate various features of Jini. We can use this here too, by supplying
simple user interfaces into the service. Such a user interface would consist
of a text field to enter a filename, and a display of the MIME type
of the filename. There is only a ``main'' role for this service, as no
administration needs to be performed.
</para>

<para>
Figure <xref linkend="FileClassifierFrame"/> 
shows what a user interface for a file classifer could look like.
<figure id="FileClassifierFrame">
<graphic fileref="images/FileClassifierFrame.gif" align="center"></graphic>
<title>FileClassifier user interface</title>
</figure>
After the service has been invoked it could pop up a dialog box 
as in figure <xref linkend="FileClassifierDialog"/>
<figure id="FileClassifierDialog">
<graphic fileref="images/FileClassifierDialog.gif" align="center"></graphic>
<title>FileClassifier return dialog</title>
</figure>
</para>

<para>
A factory for the ``main'' role that will produce an AWT <code>Frame</code> is
<programlisting>
<?program "src/ui/FileClassifierFrameFactory.java"?>
</programlisting>
</para>

<para>
The user interface object that performs this role is
<programlisting>
<?program "src/ui/FileClassifierFrame.java"?>
</programlisting>

</para>

<para>
The server which delivers both the service and the user interface has to 
prepare a <code>UIDescriptor</code>. In this case it only creates one such 
object for a single user interface, but if the server exported more interfaces
then it would simply create more descriptors
<programlisting>
<?program "src/ui/FileClassifierServer.java"?>
</programlisting>
</para>

<para>
Finally, a client needs to look for and use this user interface.
The client finds a service as usual, and then does a search through the
<code>Entry</code> objects looking for a <code>UIDescriptor</code>.
Once it has a descriptor it cab check if it meets the requirements of the
client: here we shall check if it plays a <code>MainUI</code> role,
and can generate an AWT <code>Frame</code>.
<programlisting>
<?program "src/client/TestFrameUI.java"?>
</programlisting>
</para>
</sect1>

<sect1>
<title id="Support Classes">
Support Classes
</title>

<para>
To use the service UI, additional classes are required that are not in the standard
Jini distribution. These need to be downloaded from 
<ulink url="http://www.artima.com/jini/serviceui/index.html">
http://www.artima.com/jini/serviceui/index.html</ulink>
</para>

</sect1>

<sect1>
<title id="Images">
Images
</title>
<para>
User interfaces often contain images. They may be used as icons in toolbars, for
general images on the screen, or for the icon image when the application is
iconified. When a user interface is created on the client, these images will
also need to be created and installed in the relevant part of the application.
Images are not serializable, so they cannot be created on the server and exported
as live objects in some manner. They need to be created from scratch on the
client.
</para>

<para>
The Swing package contains a convenience class <code>ImageIcon</code>. This can
be instantiated from a byte array, a filename, or most interestingly here, from
a URL. So if an image is stored where an HTTP server can find it, then the
<code>ImageIcon</code> constructor can use this directly. There may be failures in
this: the URL may be incorrect or malformed, or the image may fail to exist on the
HTTP server. Suitable code is
<programlisting>
        ImageIcon icon = null;
	try {
	    icon = new ImageIcon(new URL("http://localhost/images/mindstorms.jpg"));
	    switch (icon.getImageLoadStatus()) {
	    case MediaTracker.ABORTED:
	    case MediaTracker.ERRORED:
		System.out.println("Error");
		icon = null;
		break;
	    case MediaTracker.COMPLETE:
		System.out.println("Complete");
		break;
	    case MediaTracker.LOADING:
		System.out.println("Loading");
		break;
	    }
	} catch(java.net.MalformedURLException e) {
	    e.printStackTrace();
	}
	// icon is null or is a valid image
</programlisting>
</para>
</sect1>

<sect1>
<title id="ServiceType">
ServiceType
</title>
<para>
A user interface may use such code directly to include images.
The service may also supply useful images and other human-oriented
information in a <code>ServiceType</code> entry object.
<programlisting>
package net.jini.lookup.entry;

public class ServiceType {
    public String getDisplayName();     // Return the localized display
                                        // name of this service.
    public Image getIcon(int iconKind)  // Get an icon for this service.
    public String getShortDescription() // Return a localized short
                                        // description of this service.
}
</programlisting>
The class is supplied with empty implementations, returning <code>null</code>
for each method. A service will need to supply a subclass with useful
implementations of the methods. However, it is a useful class that could 
be used to supply images and information that may be common 
between a number of different user interfaces for a service, such as a
minimised image.
</para>
</sect1>

<!--
<sect1>
<title id="MindStorms">
MindStorms
</title>

<sect2>
<title id="RCXLoaderFrame">
RCXLoaderFrame
</title>

<para>
A MindStorms robot is primarily defined by the <code>RCXPort</code> interface.
The Jini version is defined by the <code>RCXPortImplementation</code>
interface:
<programlisting>
<?program "rcx/jini/RCXPortInterface.java"?>
</programlisting>
This allows programs to be downloaded and run, and instructions to be sent
for direct execution. As it stands, the client needs to call these interface
methods directly. To make it more useable for the human trying to drive a
robot, some sort of user interface would be useful.
</para>

<para>
There can be several general purpose user interfaces
for the RCX robot, including:
<orderedlist>
<listitem>
  Enter machine code (somehow) and download that
</listitem>
<listitem>
  Enter RCX assembler code in the form of strings, assemble and download them
</listitem>
<listitem>
  Enter NQC (Not Quite C) code, compile and download it
</listitem>
</orderedlist>
The set of RCX classes by Laverde includes a standalone application called
<code>RCXLoader</code> which does the second of these. 
We can steal code from this and some of his other classes, 
to define a class <code>RCXLoaderFrame</code>

<programlisting>
<?program "rcx/jini/RCXLoaderFrame.java"?>
</programlisting>
</para>
</sect2>

<sect2>
<title id="RCXLoaderFrameFactory">
RCXLoaderFrameFactory
</title>

<para>
The factory object for the RCX is now easy to define, it just returns a 
<code>RCXLoaderFrame</code> in the <code>getUI()</code> method:
<programlisting>
<?program "rcx/jini/RCXLoaderFrameFactory.java"?>
</programlisting>
</para>
</sect2>

<sect2>
<title id="Exporting the RCXLoaderFrameFactory">
Exporting the FrameFactory
</title>
<para>
The factory object is exported by making it a part of a <code>UIDescriptor</code>
entry object with a role, toolkit and attributes
<programlisting>
Set typeNames = new HashSet();
typeNames.add(FrameFactory.TYPE_NAME);

Set attribs = new HashSet();
attribs.add(new UIFactoryTypes(typeNames));
// add other attributes as desired

MarshalledObject factory = null;
try {
    factory = new MarshalledObject(new
				   RCXLoaderFrameFactory());
} catch(Exception e) {
    e.printStackTrace();
    System.exit(2);
}

UIDescriptor desc = new UIDescriptor(MainUI.ROLE,
                                     FrameFactory.TOOLKIT,
				     attribs,
				     factory);
Entry[] entries = {desc};

JoinManager joinMgr = new JoinManager(impl,
				      entries,
				      this,
				      new LeaseRenewalManager());
</programlisting>
</para>
</sect2>

<sect2>
<title id="Customised User Interfaces">
Customised User Interfaces
</title>

<para>
The <code>RCXLoaderFrame</code> is a general interface to any RCX robot.
Of course, there could be many other such interfaces, differing in the
classes used, the amount of internationalisation support, the appearance,
<emphasis>etc</emphasis>. All the variations, however, will just use the
standard <code>RCXPortInterface</code>, as that is all they know about.
</para>

<para>
The Lego pieces can be combined in a huge variety of ways, and the RCX itself
is programmable. So you can build an RCX car, an RCX crane, an RCX maze-runner,
and so on. Each different robot can be driven by the general interface, but
most could benefit from a custom-built interface for that type of robot.
This is typical: for example, every blender could be driven from a general
blender user interface (using the - possibly - forthcoming standard blender
interface :-). But the blenders from individual vendors would have their own
customised user interface for their brand of blender.
</para>

<para>
I have been using an RCX car. While it can do lots of things, for demonstrations
it has been convenient to use five commands: <emphasis>forward</emphasis>,
<emphasis>stop</emphasis>, <emphasis>back</emphasis>, <emphasis>left</emphasis>
and <emphasis>right</emphasis>, with a user interface of figure <xref linkend="rcxCar"/>
<figure id="rcxCar">
<graphic fileref="images/rcxCar.gif" align="center"> </graphic> 
<title>User interface for MindStorms car</title>
</figure>
In the MindStorms chapter this appearance was hard-coded into the client - which
really shouldn't know about this sort of detail.
</para>

</sect2>

<sect2>
<title id="CarJFrame">
CarJFrame
</title>

<para>
The <code>CarJFrame</code> class produces the user interface as a Swing
<code>JFrame</code>, with the buttons generating specific RCX code for this
model.
<programlisting>
<?program "rcx/jini/CarJFrame.java"?>
</programlisting>
</para>

</sect2>

<sect2>
<title id="CarJFrameFactory">
CarJFrameFactory
</title>

<para>
The factory generates a <code>CarJFrame</code> object
<programlisting>
<?program "rcx/jini/CarJFrameFactory.java"?>
</programlisting>
</para>

</sect2>

<sect2>
<title id="Exporting the CarJFrameFactory">
Exporting the FrameFactory
</title>

<para>
Both of the user interfaces discussed can be exported by expanding the set
of <code>Entry</code> objects.
<programlisting>
// generic UI
Set genericAttribs = new HashSet();
Set typeNames = new HashSet();
typeNames.add(FrameFactory.TYPE_NAME);
genericAttribs.add(new UIFactoryTypes(typeNames));
MarshalledObject genericFactory = null;
try {
    genericFactory = new MarshalledObject(new
				  RCXLoaderFrameFactory());
} catch(Exception e) {
    e.printStackTrace();
	    System.exit(2);
}
UIDescriptor genericDesc = new UIDescriptor(MainUI.ROLE,
                                            FrameFactory.TOOLKIT,
	   			            genericAttribs,
					    genericFactory);

// car UI
Set carAttribs = new HashSet();
typeNames = new HashSet();
typeNames.add(JFrameFactory.TYPE_NAME);
carAttribs.add(new UIFactoryTypes(typeNames));
MarshalledObject carFactory = null;
try {
    carFactory = new MarshalledObject(new CarJFrameFactory());
} catch(Exception e) {
    e.printStackTrace();
    System.exit(2);
}
UIDescriptor carDesc = new UIDescriptor(MainUI.ROLE,
                                        JFrameFactory.TOOLKIT,
					carAttribs,
					carFactory);

Entry[] entries = {genericDesc, carDesc};

JoinManager joinMgr = new JoinManager(impl,
				      entries,
				      this,
				      new LeaseRenewalManager());
</programlisting>
</para>
</sect2>

<sect2>
<title id="The RCX Client">
The RCX Client
</title>
<para>
The following client will start up all user interfaces that it understands

<programlisting>
<?program "client/TestRCX2.java"?>
</programlisting>
</para>
</sect2>

</sect1>
-->

<sect1>
<title id="Summary">
Summary
</title>
<para>
The ui-service group is evolving a standard mechanism for services to distribute
user-interfaces for Jini services. The preference is to do this by entry objects.
</para>
</sect1>

&copyright;
</chapter>
