001: package prefuse.render;
002:
003: import prefuse.data.expression.Predicate;
004: import prefuse.data.expression.parser.ExpressionParser;
005: import prefuse.util.PredicateChain;
006: import prefuse.visual.EdgeItem;
007: import prefuse.visual.VisualItem;
008:
009: /**
010: * <p>Default factory implementation from which to retrieve VisualItem
011: * renderers.</p>
012: *
013: * <p>
014: * This class supports the use of a default renderer for EdgeItems (the default
015: * edge renderer) and another for all other non-edge VisualItems (the default
016: * item renderer). In addition, any number of additional Renderer mapping rules
017: * can be added, by specifying a Predicate to apply and a Renderer to return
018: * for matching items. Predicate/Renderer mappings are checked in the order in
019: * which they were added to the factory.
020: * </p>
021: *
022: * <p>If left unspecified, a {@link ShapeRenderer} is used as the default
023: * item renderer and an {@link EdgeRenderer} instance is used as the default
024: * edge renderer.</p>
025: *
026: * <p>For example, the following code snippet creates a new
027: * DefaultRendererFactory, changes the default edge renderer to be an
028: * EdgeRenderer using curved edges, and adds a new rule which maps items in
029: * the group "data" to a text renderer that pulls its text from a field named
030: * "label".</p>
031: * <pre>
032: * DefaultRendererFactory rf = new DefaultRendererFactory();
033: * rf.setDefaultEdgeRenderer(new EdgeRenderer(Constants.EDGE_TYPE_CURVE);
034: * rf.add("INGROUP('data')", new LabelRenderer("label");
035: * </pre>
036: *
037: * @author <a href="http://jheer.org">jeffrey heer</a>
038: */
039: public class DefaultRendererFactory implements RendererFactory {
040:
041: private PredicateChain m_chain = new PredicateChain();
042: private Renderer m_itemRenderer;
043: private Renderer m_edgeRenderer;
044:
045: /**
046: * Default Constructor. A ShapeRenderer instance will be used for the
047: * default item renderer and an EdgeRenderer instance will be used for the
048: * default edge renderer.
049: * @see ShapeRenderer
050: * @see EdgeRenderer
051: */
052: public DefaultRendererFactory() {
053: this (new ShapeRenderer());
054: }
055:
056: /**
057: * Constructor. Creates a new DefaultRendererFactory with the specified
058: * default item renderer. An EdgeRenderer instance will be used for the
059: * default edge renderer.
060: * @param itemRenderer the default item renderer. This is the default for
061: * rendering all items except EdgeItem instances.
062: * @see EdgeRenderer
063: */
064: public DefaultRendererFactory(Renderer itemRenderer) {
065: this (itemRenderer, new EdgeRenderer());
066: }
067:
068: /**
069: * Constructor. Creates a new DefaultRendererFactory with the specified
070: * default item and edge renderers.
071: * @param itemRenderer the default item renderer. This is the default for
072: * rendering all items except EdgeItem instances.
073: * @param edgeRenderer the default edge renderer. This is the default for
074: * rendering EdgeItem instances.
075: */
076: public DefaultRendererFactory(Renderer itemRenderer,
077: Renderer edgeRenderer) {
078: m_itemRenderer = itemRenderer;
079: m_edgeRenderer = edgeRenderer;
080: }
081:
082: // ------------------------------------------------------------------------
083:
084: /**
085: * Sets the default renderer. This renderer will be returned by
086: * {@link #getRenderer(VisualItem)} whenever there are no matching
087: * predicates and the input item <em>is not</em> an EdgeItem. To set the
088: * default renderer for EdgeItems, see
089: * {@link #setDefaultEdgeRenderer(Renderer)}.
090: * @param r the Renderer to use as the default
091: * @see #setDefaultEdgeRenderer(Renderer)
092: */
093: public void setDefaultRenderer(Renderer r) {
094: m_itemRenderer = r;
095: }
096:
097: /**
098: * Gets the default renderer. This renderer will be returned by
099: * {@link #getRenderer(VisualItem)} whenever there are no matching
100: * predicates and the input item <em>is not</em> an EdgeItem.
101: * @return the default Renderer for non-edge VisualItems
102: */
103: public Renderer getDefaultRenderer() {
104: return m_itemRenderer;
105: }
106:
107: /**
108: * Sets the default edge renderer. This renderer will be returned by
109: * {@link #getRenderer(VisualItem)} whenever there are no matching
110: * predicates and the input item <em>is</em> an EdgeItem. To set the
111: * default renderer for non-EdgeItems, see
112: * {@link #setDefaultRenderer(Renderer)}.
113: * @param r the Renderer to use as the default for EdgeItems
114: * @see #setDefaultRenderer(Renderer)
115: */
116: public void setDefaultEdgeRenderer(Renderer r) {
117: m_edgeRenderer = r;
118: }
119:
120: /**
121: * Gets the default edge renderer. This renderer will be returned by
122: * {@link #getRenderer(VisualItem)} whenever there are no matching
123: * predicates and the input item <em>is</em> an EdgeItem.
124: * @return the default Renderer for EdgeItems
125: */
126: public Renderer getDefaultEdgeRenderer() {
127: return m_edgeRenderer;
128: }
129:
130: /**
131: * Adds a new mapping to this RendererFactory. If an input item to
132: * {@link #getRenderer(VisualItem)} matches the predicate, then the
133: * corresponding Renderer will be returned. Predicates are evaluated in the
134: * order in which they are added, so if an item matches multiple
135: * predicates, the Renderer for the earliest match will be returned.
136: * @param p a Predicate for testing a VisualItem
137: * @param r the Renderer to return if an item matches the Predicate
138: */
139: public void add(Predicate p, Renderer r) {
140: m_chain.add(p, r);
141: }
142:
143: /**
144: * Adds a new mapping to this RendererFactory. If an input item to
145: * {@link #getRenderer(VisualItem)} matches the predicate, then the
146: * corresponding Renderer will be returned. Predicates are evaluated in the
147: * order in which they are added, so if an item matches multiple
148: * predicates, the Renderer for the earliest match will be returned.
149: * @param predicate a String in the prefuse expression language. This
150: * String will be parsed to create a corresponding Predicate instance.
151: * @param r the Renderer to return if an item matches the Predicate
152: */
153: public void add(String predicate, Renderer r) {
154: Predicate p = (Predicate) ExpressionParser.parse(predicate);
155: add(p, r);
156: }
157:
158: /**
159: * Return a Renderer instance for the input VisualItem. The VisualItem
160: * is matched against the registered Predicates, and if a match is found
161: * the corresponding Renderer is returned. Predicate matches are evaluated
162: * in the order in which Predicate/Renderer mappings were added to this
163: * RendererFactory. If no matches are found, either the default renderer
164: * (for all VisualItems except EdgeItems) or the default edge renderer (for
165: * EdgeItems) is returned.
166: */
167: public Renderer getRenderer(VisualItem item) {
168: Renderer r = (Renderer) m_chain.get(item);
169: if (r != null)
170: return r;
171: else if (item instanceof EdgeItem)
172: return m_edgeRenderer;
173: else
174: return m_itemRenderer;
175: }
176:
177: } // end of class DefaultRendererFactory
|