This interface defines a nested Graph that appears to be
a single Node from the perspective of its parent. This technique
allows unlimited nesting of graphs inside graphs.
There are number of consequences of representing an entire Graph as a single Node.
First of all, such a nested Graph (from now on referred to as a Subgraph)
must be a Node from the parent's point of view. The parent Graph does not need to
know whether a particular Node is actually a Subgraph or not. This is a major
advantage of the subgraphing approach. Each Subgraph may be
handled like an ordinary Node in a particular context.
When a Node is used to represent an entire Graph, however, the interface
Node no longer suffices. A more general interface needs to exist that allows
us to focus on the Subgraph as a Graph instance as well. Therefore, this
interface extends the GraphObjectContainer as well.
The following diagram illustrates the isomorphism of VisualSubgraph and VisualNode.
The fact that both a VisualGraphView and a VisualSubgraph are visual representations of
entire graphs is apparent, since both types inherit from the common interface
VisualGraphObjectContainer.
The tight structural coupling between model and view objects can be seen
in the following model diagram. Please note that model classes do not provide a
top-level type like the VisualGraphView class.
Please note that interfaces GraphObjectContainer and VisualGraphObjectContainer
can (and should) be used in most occasions where these interfaces are being used:
Graph,
Subgraph,
VisualGraph,
VisualGraphView and
VisualSubgraph
These derived interfaces are not known by any centralized Container objects.
Finally, the interface Edge cannot be used in place of a Subgraph.
Since objects of type Subgraph (and VisualSubgraph) can be nested inside each other,
it often becomes necessary to traverse a given hierarchy. This can be achieved by
implementing interface GraphVisitor in the model or VisualGraphVisitor in the view.
Example 1.6. Traversal of nested Subgraphs
void traverse(Graph graph)
{
// Visit all nested subgraphs and print out their hashcodes.
// The used order for traversal is POST_ORDER.
// Alternatively GraphVisitor.PRE_ORDER can be specified.
graph.visitSubgraphs(
new GraphVisitor ()
{
public int getOrder()
{
return GraphVisitor.POST_ORDER;
}
public void visit(Subgraph subgraph, int level)
{
System.err.println ("visiting subgraph ... "
+ System.identityHashCode(subgraph));
}
});
}
Example 1.7. Traversal of nested VisualSubgraphs
void traverseSubGraphs(VisualGraphView vgv)
{
// Visit all nested visualsubgraphs and print out their hashcodes.
// The used order for traversal is POST_ORDER.
// Alternatively VisualGraphVisitor.PRE_ORDER can be specified.
vgv.visitSubgraphs(new VisualGraphVisitor()
{
public int getOrder()
{
return VisualGraphVisitor.POST_ORDER;
}
public void visit(
VisualSubgraph visualsubgraph,
VisualGraph visualgraph,
VisualGraph parentvisualgraph,
int level)
{
System.err.println("visiting visualsubgraph ... "
+ System.identityHashCode(visualsubgraph));
}
});
}
© 2004, 2005 Tensegrity Software GmbH