Table of Contents
This chapter will introduce you to the Renderer concepts and related
components of the Tensegrity API. To understand these concepts, it is helpful to
understand how a VisualGraph containing multiple Composite objects is
drawn. The following sequence diagram illustrates this process clearly.
Note that the method signatures are simplified in order to keep the
diagram clear and more readable.
Method draw(Renderer, Device, Tranform2D) of a
CompositeView is called whenever a VisualGraphView is drawn. An implementation
class will iterate over all contained BaseComposite instances and obtain
the RenderingData for every embedded Primitive. This data is then passed
in method render(RenderingData, Device) called
on the specified Renderer instance.
Each RenderingData object is a collection of attributes specifying the
rendering process. This collection contains an attribute with the key
RenderingData.KEY_ILLUSTRATOR that contains the
Illustrator for the graphical object to be illustrated. A call to method
illustrate(Device) on this object triggers
various (at least one) calls to the different draw()
methods interface Device provides.
Now that the collaborative drawing process of the Tensegrity API has been clarified,
let us have a look at the specifics of the objects involved. This following
sections deal with all aspects of a Renderer object.
The interfaces CompositeView, VisualGraphView, GraphPanel and BaseComposite
were introduced in part
“Creating and Modeling Graphs” of this manual.
The Renderer interface defines a role which is capable of
rendering a graphical object in a certain context. Graphical objects are
described through an object of type RenderingData. To render
a graphical object, a Renderer uses an Illustrator
instance as the RenderingData key. A Renderer can
also be seen as a filter that modifies the attributes of the graphical
object with respect to the Renderer itself and its configuration.
The configuration of a Renderer is represented by a
RendererConfiguration object and is accessible through
method getConfiguration().
Normally a Renderer is invoked by a call to method
render(). This method adjusts the given
RenderingData as arranged and then calls the
Illustrator to output the graphical object using the
modified RenderingData onto the given Device.
Renderers can be concatenated in a
RendererChain. This way the functionalities of multiple
Renderer instances can be used for an output process. In a
chain the method render() gets called by the
RendererChain only for the last Renderer
object in the chain, because this method outputs the given data to the
given Device. Method adjustData() gets called
that on all predecessors and modifies the RenderingData
according to the Renderer object and its configuration.
REVIEWJAVADOC: (Renderer.java) The previous paragraph also has a couple of confusing sentences that need to be slightly rewritten.
When a VisualGraph is rendered, its visual nodes and egdes are drawn according
to the Renderer implementation. In other words, each Renderer class
interprets the GeometryItem and Format objects in a unique way. The following
class diagram shows interface Renderer and all of its implementation classes.
Class RendererConfiguration provides configuration settings
for a Renderer by providing a set of Attribute
objects whose names are defined by constants of this class. This class
supports the configuration of the following items:
| Attribute Name | Description |
|---|---|
SUPPRESS_MARKERS |
Suppresses the rendering of markers
MarkerFormat
|
SUPPRESS_TEXT |
Suppresses the rendering of text
FontFormat
|
SUPPRESS_SELECTION_MARKER |
Suppresses the rendering of selection markers
InteractionContext
|
TEXT_CUTOFF | Defines a cutoff value for text rendering. This means if the height of the rendered text is smaller than the defined value, the text will not be rendered. |
The following methods are provided to work with and modify the provided
Attribute instances:
Attribute getAttribute(String)
Returns the Attribute of the configuration item
specified by attributename or null if the
given name specifies no configuration item.
Iterator getAttributesIterator()
Returns an Iterator for all the names that identify
valid configuration items. The iterator returns instances of type
Attribute.
REVIEWJAVADOC: RenderingData.java : Ist das hier eine abgespeckte Schnittstelle zur Primitive interface.
The RenderingData class is used to describe the attributes of a
graphical object. It consists of several RenderingDataKey
objects that represent both the attributes of a graphical object and provide
an Illustrator to draw it. The following keys are supported:
KEY_STROKE
The attributes of the StrokeFormat the graphical object
may use.
KEY_PAINT
The attributes of the PaintFormat the graphical object
may use.
KEY_TEXT
The attributes of the text the graphical object may consist of.
KEY_MARKER_BEGIN
The attributes of the MarkerFormat a line object may use
at the beginning of it.
KEY_MARKER_END
The attributes of the MarkerFormat a line object may use at the
end of it.
KEY_ILLUSTRATOR
The Illustrator instance that is responsible for
drawing the graphical object. This key is not optional and must
be given.
RenderingDataKey objects are frequently used in conjunction with
objects of class RenderingData. Class RenderingData
provides the supported keys as static constants.
Interface RendererChain defines a component which concatenates
two Renderer objects. In order to fulfill this responsibility,
a RendererChain must be provided with and return source and
target Rendererinstances.
The source Renderer is invoked first and then the target
Renderer is called. The concatenated Renderer
objects may of course be instances of the RendererChain
interface, so that a deeper Renderer chain may be built.
With the exception of the final instance, all Renderer objects
in the chain have their adjustData method invoked. The last
Renderer, however, has its render() method called
so that it renders the given RenderingData onto the specified
Device.
Implementations of interface Illustrator are responsible for
drawing graphical objects onto a Device without using the Java
class Shape. Because the Java Graphics class uses
a PathIterator instance to output a Shape, the
output is extremely time expensive. Therefore, each Primitive
to be drawn uses its own Illustrator object, which requires
much less time for the output process. Moreover, it was a design intention
to decouple the implementation from package awt. This
allows easy switching to different graphical platforms, such as the
Standard Widget Toolkit (SWT) from the Eclipse project.
REVIEWJAVADOC: (Illustrator.java) Because the javadoc for the Renderer class is not very clear, it might help to describe the responsibility of this interface in light of the existence of the Renderer interface. In other words, what are the main differences of the different responsibilities? Lets also talk about what one expects from an implementation without using that word in the responsiblity statement.
© 2004, 2005 Tensegrity Software GmbH