"Show me your flowchart and conceal your tables, and I shall continue to be mystified. Show me your tables, and I won't usually need your flowchart; it'll be obvious." — Fred Brooks, The Mythical Man Month
Looking at the diagram below, the class Multivalent
,
at top center, is the central point for shared state.
It holds Browser
s, which correspond to top-level windows.
Each Browser
holds a document tree,
with exactly one Root
.
The document tree includes in one unified tree
both graphical user interface (GUI) elements
such as the menubar and toolbar (shown in the bottom half of the diagram
in the leftmost of the three rough columns),
and tree nodes that correspond to document content (middle column).
Regardless of whether the concrete document being displayed
is PDF, HTML, DVI, manual pages, scanned paper, or something else,
the document tree looks the same at this level.
All of the functionality in the system is implemented by
groups or Layer
s of
Behavior
s (rightmost column),
which can apply to the entire
Browser
if they hook on to the Root
,
or document "genres" such as "HTML" and "PDF",
or specific documents by hooking onto Document
s.
The diagram depicts the high level data structures;
in dynamic operation, control flow passes through the tree and
through behaviors in protocols:
restore
, format
, paint
,
events
, semantic events
, and so on;
all activity pertaining to a particular function should be done
in the corresponding protocol, which is carefully sequenced
under system control so as to avoid conflicts among competing classes.
We now examine the diagram in more detail.
The class Multivalent
starts up the system when invoked
by the Java Virtual Machine. It holds shared state such as
preferences (including arbitrary persisten variables, and
mappings from MIME type or file suffix to
behavior that reads that document format),
hooks to the network file cacheing,
and methods that can create a new Browser
or fetch a previously created one by name.
Any class anywhere can obtain the singleton instance of this class
with the static
call Multivalent.getMultivalent()
.
A Browser
corresponds to an independent window
that can be moved about the screen, iconified, and so on.
It holds state shared within a Browser
such as the selection and the focus subwindow.
It interfaces between the operating system and the Multivalent world:
paint requests and mouse and keyboard events initiated by the user
come through the OS to this class, which then
routes them to the appropriate protocol for passing through the
tree or behaviors.
All visual content is drawn via the document tree
with a single Root
.
Tree nodes have the tree navigation facilities common to all tree packages,
such as getting a child (getChild()
),
getting one's parent (getParentNode()
),
getting one's name (getName()
),
and so on.
The Root
is special in that it is a gateway between
the document tree and the containing Browser
.
As a convenience, the method getRoot()
on any Node
climbs up the tree and returns the Root
(Diagram also
available in .pdf
for printing.)
The document tree contains both GUI nodes and nodes corresponding to concrete document formats. In both cases, the "structure" is represented in internal nodes, and "words" (text, image, button) in nodes at or near the leaves. In most other GUI toolkits, GUI elements are typically organized in a tree with layout widgets containing more specialized widgets as leaves. In Multivalent, which focuses on human readable documents, GUI widgets and text/image nodes are the same: a button is simply a word with a specialized function when you click on it, and widget layout is done with the same layout functions used for, say, laying out an HTML table. This has benefits in both directions: when documents are faced with, say, a HTML form, the tree is uniform, and there is no need to bridge two different systems, tree nodes and system GUI widgets. In the other direction, GUI widgets benefit from sophisticated display (buttons can display a HTML table and be controlled by stylesheets).
In the GUI subtree specifically (left column),
VMenuButton
, which displays a label like "File"
or "Edit" in the menubar and when clicked
displays its associated menu, is an internal node whose
appearance is given by its subtree, which can be of arbitrary complexity,
anything from a simple ASCII text to a full HTML table to a page of PDF.
VMenuButton
s can have explicit menus in the tree, but often
they generate them on demand by creating an empty menu with
a label and passing it to all the Behavior
in the system
to add entries.
The subtree corresponding to the content of the concrete document
format (middle column) represents the structure of the document in
internal nodes and the words and images and shapes in leaves. For
SGML and XML the structure is identical to the parse tree, for HTML it
is the corrected parse tree with appearance tags like I, B, TT, and
EMPH separated out as Span
s (see below), and for PDF and
scanned paper the only available structure is often just text regions.
The Document
at the head of the subtree
represents an independent document in that it has a URI,
a stylesheet,
and, as available, attributes for author, title, and so on.
Document
has a link to the Behavior
s
associated with it, and in fact Root
is a subclass of
Document
with a link to the Behavior
s
operational on all Document
s.
Behavior
implement all the user-level functionality
of the system. They are grouped in Layer
s,
and the list of Behavior
in a hub is read from
a XML hub document.
System.hub
, most important hub, is associated with the
Root
and establishes all those Behavior
s
that are always active no matter if the document displayed is HTML, PDF,
or something else.
Associated with a particular Document
is a genre hub,
such as for one for HTML or scanned paper. Often genre hubs share
via inclusion other hubs; for instance, DVI and scanned paper share the
"fixed format" hub.
To read new documents, format them, paint them on the screen, and
respond to events,
the system initiates a protocol.
Depending on the protocol, the system passes control through tree
Node
s (a tree-based protocol)
or through the Behavior
s in the
Root
and the current Document
(a round-robin protocol).
Behavior
s can also be invoked during tree-based protocols
by observing the tree at any node; when control passes
through this node in the tree walk, the observing Behavior
is notified before and after the node itself
is traversed.
An example of such a Behavior
is
one that implements key bindings;
it listens for key events (java.awt.event.KeyEvent
)
that matches a binding and takes action on a match,
and then has the option of short-circuiting further propagation
of the event.
A widely use Behavior
type,
the Span
is often used for hyperlinks and highlight regions.
It hooks into the tree at two points
and can affect appearance and receive events
at any point inbetween, cutting across structural boundaries.
In the diagram, the generic base class Span
is used to associate a label, such as "i", "tt", or "emph" in HTML,
over some text for the stylesheet to determine its appearance.