Chapter 14. Renderer and Device

Table of Contents

Interface Renderer
RendererConfiguration
RenderingData
RendererChain
Illustrator
Device
Interface Device

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.

Figure 14.1. Sequence Diagram Rendering

Sequence Diagram Rendering

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.

Note

The interfaces CompositeView, VisualGraphView, GraphPanel and BaseComposite were introduced in part “Creating and Modeling Graphs” of this manual.

Interface Renderer

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.

Figure 14.2. Classdiagram Renderer

Classdiagram Renderer

RendererConfiguration

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 NameDescription
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.

RenderingData

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.

RendererChain

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.

Illustrator

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.