package prefuse.render;
import prefuse.data.expression.Predicate;
import prefuse.data.expression.parser.ExpressionParser;
import prefuse.util.PredicateChain;
import prefuse.visual.EdgeItem;
import prefuse.visual.VisualItem;
/**
* <p>Default factory implementation from which to retrieve VisualItem
* renderers.</p>
*
* <p>
* This class supports the use of a default renderer for EdgeItems (the default
* edge renderer) and another for all other non-edge VisualItems (the default
* item renderer). In addition, any number of additional Renderer mapping rules
* can be added, by specifying a Predicate to apply and a Renderer to return
* for matching items. Predicate/Renderer mappings are checked in the order in
* which they were added to the factory.
* </p>
*
* <p>If left unspecified, a {@link ShapeRenderer} is used as the default
* item renderer and an {@link EdgeRenderer} instance is used as the default
* edge renderer.</p>
*
* <p>For example, the following code snippet creates a new
* DefaultRendererFactory, changes the default edge renderer to be an
* EdgeRenderer using curved edges, and adds a new rule which maps items in
* the group "data" to a text renderer that pulls its text from a field named
* "label".</p>
* <pre>
* DefaultRendererFactory rf = new DefaultRendererFactory();
* rf.setDefaultEdgeRenderer(new EdgeRenderer(Constants.EDGE_TYPE_CURVE);
* rf.add("INGROUP('data')", new LabelRenderer("label");
* </pre>
*
* @author <a href="http://jheer.org">jeffrey heer</a>
*/
public class DefaultRendererFactory implements RendererFactory {
private PredicateChain m_chain = new PredicateChain();
private Renderer m_itemRenderer;
private Renderer m_edgeRenderer;
/**
* Default Constructor. A ShapeRenderer instance will be used for the
* default item renderer and an EdgeRenderer instance will be used for the
* default edge renderer.
* @see ShapeRenderer
* @see EdgeRenderer
*/
public DefaultRendererFactory() {
this(new ShapeRenderer());
}
/**
* Constructor. Creates a new DefaultRendererFactory with the specified
* default item renderer. An EdgeRenderer instance will be used for the
* default edge renderer.
* @param itemRenderer the default item renderer. This is the default for
* rendering all items except EdgeItem instances.
* @see EdgeRenderer
*/
public DefaultRendererFactory(Renderer itemRenderer) {
this(itemRenderer, new EdgeRenderer());
}
/**
* Constructor. Creates a new DefaultRendererFactory with the specified
* default item and edge renderers.
* @param itemRenderer the default item renderer. This is the default for
* rendering all items except EdgeItem instances.
* @param edgeRenderer the default edge renderer. This is the default for
* rendering EdgeItem instances.
*/
public DefaultRendererFactory(Renderer itemRenderer, Renderer edgeRenderer)
{
m_itemRenderer = itemRenderer;
m_edgeRenderer = edgeRenderer;
}
// ------------------------------------------------------------------------
/**
* Sets the default renderer. This renderer will be returned by
* {@link #getRenderer(VisualItem)} whenever there are no matching
* predicates and the input item <em>is not</em> an EdgeItem. To set the
* default renderer for EdgeItems, see
* {@link #setDefaultEdgeRenderer(Renderer)}.
* @param r the Renderer to use as the default
* @see #setDefaultEdgeRenderer(Renderer)
*/
public void setDefaultRenderer(Renderer r) {
m_itemRenderer = r;
}
/**
* Gets the default renderer. This renderer will be returned by
* {@link #getRenderer(VisualItem)} whenever there are no matching
* predicates and the input item <em>is not</em> an EdgeItem.
* @return the default Renderer for non-edge VisualItems
*/
public Renderer getDefaultRenderer() {
return m_itemRenderer;
}
/**
* Sets the default edge renderer. This renderer will be returned by
* {@link #getRenderer(VisualItem)} whenever there are no matching
* predicates and the input item <em>is</em> an EdgeItem. To set the
* default renderer for non-EdgeItems, see
* {@link #setDefaultRenderer(Renderer)}.
* @param r the Renderer to use as the default for EdgeItems
* @see #setDefaultRenderer(Renderer)
*/
public void setDefaultEdgeRenderer(Renderer r) {
m_edgeRenderer = r;
}
/**
* Gets the default edge renderer. This renderer will be returned by
* {@link #getRenderer(VisualItem)} whenever there are no matching
* predicates and the input item <em>is</em> an EdgeItem.
* @return the default Renderer for EdgeItems
*/
public Renderer getDefaultEdgeRenderer() {
return m_edgeRenderer;
}
/**
* Adds a new mapping to this RendererFactory. If an input item to
* {@link #getRenderer(VisualItem)} matches the predicate, then the
* corresponding Renderer will be returned. Predicates are evaluated in the
* order in which they are added, so if an item matches multiple
* predicates, the Renderer for the earliest match will be returned.
* @param p a Predicate for testing a VisualItem
* @param r the Renderer to return if an item matches the Predicate
*/
public void add(Predicate p, Renderer r) {
m_chain.add(p, r);
}
/**
* Adds a new mapping to this RendererFactory. If an input item to
* {@link #getRenderer(VisualItem)} matches the predicate, then the
* corresponding Renderer will be returned. Predicates are evaluated in the
* order in which they are added, so if an item matches multiple
* predicates, the Renderer for the earliest match will be returned.
* @param predicate a String in the prefuse expression language. This
* String will be parsed to create a corresponding Predicate instance.
* @param r the Renderer to return if an item matches the Predicate
*/
public void add(String predicate, Renderer r) {
Predicate p = (Predicate)ExpressionParser.parse(predicate);
add(p, r);
}
/**
* Return a Renderer instance for the input VisualItem. The VisualItem
* is matched against the registered Predicates, and if a match is found
* the corresponding Renderer is returned. Predicate matches are evaluated
* in the order in which Predicate/Renderer mappings were added to this
* RendererFactory. If no matches are found, either the default renderer
* (for all VisualItems except EdgeItems) or the default edge renderer (for
* EdgeItems) is returned.
*/
public Renderer getRenderer(VisualItem item) {
Renderer r = (Renderer)m_chain.get(item);
if ( r != null )
return r;
else if ( item instanceof EdgeItem )
return m_edgeRenderer;
else
return m_itemRenderer;
}
} // end of class DefaultRendererFactory