Coverage details for edu.uci.ics.jung.visualization.graphdraw.SettableRenderer

LineHitsSource
1 /*
2  * Copyright (c) 2003, the JUNG Project and the Regents of the University of
3  * California All rights reserved.
4  *
5  * This software is open-source under the BSD license; see either "license.txt"
6  * or http://jung.sourceforge.net/license.txt for a description.
7  */
8 package edu.uci.ics.jung.visualization.graphdraw;
9  
10 import java.awt.BasicStroke;
11 import java.awt.Color;
12 import java.awt.Graphics;
13 import java.awt.Graphics2D;
14 import java.awt.Stroke;
15  
16 import edu.uci.ics.jung.graph.DirectedEdge;
17 import edu.uci.ics.jung.graph.Edge;
18 import edu.uci.ics.jung.graph.UndirectedEdge;
19 import edu.uci.ics.jung.graph.Vertex;
20 import edu.uci.ics.jung.graph.decorators.EdgeColorFunction;
21 import edu.uci.ics.jung.graph.decorators.EdgeStringer;
22 import edu.uci.ics.jung.graph.decorators.EdgeThicknessFunction;
23 import edu.uci.ics.jung.graph.decorators.StringLabeller;
24 import edu.uci.ics.jung.graph.decorators.VertexColorFunction;
25 import edu.uci.ics.jung.graph.predicates.EdgePredicate;
26 import edu.uci.ics.jung.graph.predicates.SelfLoopEdgePredicate;
27 import edu.uci.ics.jung.visualization.AbstractRenderer;
28 import edu.uci.ics.jung.visualization.contrib.Arrow;
29  
30 /**
31  * A renderer with all sorts of buttons to press and dials to turn. In general,
32  * if a function is available to get an answer to questions of color. Otherwise,
33  * the set fields are used.
34  * <p>
35  * The default is to paint vertices with Black foreground text and Red
36  * backgrounds. Picked vertices are orange. [Whether a vertex is Picked is
37  * resolved with <tt>v.getUserDatum(_VisualizationViewer.VIS_KEY);</tt>]
38  *
39  * <p>
40  * Note that setting a stroke width other than 1 is likely to slow down the
41  * visualization noticably, as is using transparency.
42  *
43  * @deprecated Replaced by PluggableRenderer.
44  * @author danyelf
45  */
46 public class SettableRenderer extends AbstractRenderer {
47  
480    protected Color vertexFGColor = Color.BLACK;
49  
500    protected Color vertexPickedColor = Color.ORANGE;
51  
520    protected Color vertexBGColor = Color.RED;
53  
54     protected VertexColorFunction vertexColorFunction;
55  
56     protected EdgeThicknessFunction edgeThicknessFunction;
57  
58     protected int edgeThickness;
59  
600    protected Color edgeColor = Color.BLACK;
61  
62     protected EdgeColorFunction edgeColorFunction;
63  
64     protected StringLabeller mStringLabeller;
65  
660    protected boolean mShouldDrawSelfLoops = false;
67  
680    protected boolean mDrawLightBoxes = true;
69  
700    protected boolean mShouldDrawArrowsUndirected = false;
71  
720    protected boolean mShouldDrawArrowsDirected = true;
73  
74     protected Arrow mArrow;
75  
76     protected EdgeStringer mEdgeLabelFunction;
77  
78     protected int mLineHeight;
79  
800    protected static EdgePredicate self_loop = SelfLoopEdgePredicate.getInstance();
81     
82     /**
83      * This variant simply renders vertices as small empty boxes without labels.
84      */
850    public SettableRenderer() {
860        this.mStringLabeller = null;
870    }
88  
89     /**
90      * Creates a SettableRenderer that will be drawn in the "heavy" style: a box
91      * around the label
92      *
93      * @param sl
94      */
950    public SettableRenderer(StringLabeller sl) {
960        this.mStringLabeller = sl;
970    }
98  
99     /**
100      * Creates a SettableRenderer that will label edges with the given EdgeStringer.
101      * (You may want EdgeWeightLabellerStringer, which uses an EdgeWeightLabeller to
102      * label the weights.)
103      * @param sl
104      * @param el
105      */
1060    public SettableRenderer(StringLabeller sl, EdgeStringer el) {
1070        this.mStringLabeller = sl;
1080        this.mEdgeLabelFunction = el;
1090    }
110  
111     /**
112      * Creates a SettableRenderer that will be drawn in the "light" style: a
113      * colored box next to text, instead of text overlaying the box.
114      */
115     public void setLightDrawing(boolean b) {
1160        this.mDrawLightBoxes = b;
1170    }
118  
119     public void setStringLabeller(StringLabeller sl) {
1200        this.mStringLabeller = sl;
1210    }
122  
123     public void setEdgeColor(Color c) {
1240        edgeColor = c;
1250    }
126  
127     /**
128      * Edges are drawn by calling <tt>EdgeColorFunction</tt> with the edge, to
129      * decide how it is to be drawn.
130      *
131      * @param ecf
132      */
133     public void setEdgeColorFunction(EdgeColorFunction ecf) {
1340        this.edgeColorFunction = ecf;
1350    }
136  
137     /**
138      * Forces all edges to draw with this thickness. Sets the edge thickness
139      * function to null.
140      *
141      * @param i
142      */
143     public void setEdgeThickness(int i) {
1440        this.edgeThicknessFunction = null;
1450        this.edgeThickness = i;
1460    }
147  
148     /**
149      * This version takes a function that dynamically chooses an edge thickness.
150      *
151      * @param etf
152      */
153     public void setEdgeThicknessFunction(EdgeThicknessFunction etf) {
1540        this.edgeThicknessFunction = etf;
1550        this.edgeThickness = 0;
1560    }
157  
158     /**
159      * Sets whether the system should draw arrows on directed edges. By default,
160      * yes.
161      *
162      * @param b
163      */
164     public void setShouldDrawDirectedArrows(boolean b) {
1650        this.mShouldDrawArrowsDirected = b;
1660    }
167  
168     /**
169      * Sets whether the system should draw arrows on directed edges. By default,
170      * yes.
171      *
172      * @param b
173      */
174     public void setShouldDrawUndirectedArrows(boolean b) {
1750        this.mShouldDrawArrowsUndirected = b;
1760    }
177     
178     /**
179      * Sets whether the system should draw self-loops. By default, no.
180      * @param b
181      */
182     public void setShouldDrawSelfLoops( boolean b ) {
1830        this.mShouldDrawSelfLoops = b;
1840    }
185  
186     /**
187      * Paints the edge in the color specified by the EdgeColorFunction or the
188      * hard-set color, and at the thickness set with an
189      * <tt>EdgeThicknessFunction</tt>. Draws a self-loop if
190      * <tt>shouldDrawSelfLoops()</tt> has been set (by default, no); draws an
191      * arrow on directed edges if <tt>shouldDrawDirectedArrows()</tt> has been
192      * set (by default, yes) and on both ends of undirected edges if
193      * <tt>shouldDrawUndirectedArrows()</tt> has been set (by default, false).
194      * Calls either drawEdge or drawEdgeSimple. Draws one arrow for
195      * self-loops if needed. Note that x1, y1 always correspond to
196      * e.getEndpoints.getFirst() and x2, y2 always correspond to
197      * e.getEndpoints.getSecond()
198      *
199      * @see EdgeThicknessFunction EdgeThicknessFunction
200      * @see EdgeColorFunction EdgeColorFunction
201      */
202     public void paintEdge(Graphics g, Edge e, int x1, int y1, int x2, int y2) {
2030        Graphics2D g2d = (Graphics2D) g;
2040        mLineHeight = g2d.getFontMetrics().getHeight();
205  
206         float edgeWidth;
2070        if (edgeThicknessFunction != null)
2080            edgeWidth = edgeThicknessFunction.getEdgeThickness(e);
209         else
2100            edgeWidth = edgeThickness;
211  
2120        if (edgeColorFunction == null) {
2130            g.setColor(edgeColor);
214         } else {
2150            g.setColor(edgeColorFunction.getEdgeColor(e));
216         }
217  
2180        if (edgeWidth == 1)
2190            drawEdgeSimple(g, e, x1, y1, x2, y2);
220         else
2210            drawEdge(edgeWidth, g, e, x1, y1, x2, y2);
222  
2230        if (mShouldDrawArrowsDirected && e instanceof DirectedEdge) {
2240            drawArrowhead(g2d, e, x1, y1, x2, y2);
225         }
2260        if (mShouldDrawArrowsUndirected && e instanceof UndirectedEdge) {
2270            drawArrowhead(g2d, e, x1, y1, x2, y2);
2280            drawArrowhead(g2d, e, x2, y2, x1, y1);
229         }
230  
2310        String label = (mEdgeLabelFunction == null) ? null : mEdgeLabelFunction
232                 .getLabel(e);
2330        if (label != null) {
2340            labelEdge(g2d, e, label, x1, x2, y1, y2);
235         }
2360    }
237  
238     /**
239      * Labels the edge at the half-way point (if undirected) or three-quarters
240      * if directed or 15 pixels above the vertex if self-loop.
241      *
242      * @param g2d
243      * @param e
244      * @param label
245      * @param x1
246      * @param x2
247      * @param y1
248      * @param y2
249      */
250     public void labelEdge(Graphics2D g2d, Edge e, String label, int x1, int x2,
251             int y1, int y2) {
252  
2530        if (self_loop.evaluate(e)) {
2540            g2d.drawString(label, x1 - 3 , y1 - 10 - mLineHeight/2);
2550            return;
256         }
257         
2580        int distX = x2 - x1;
2590        int distY = y2 - y1;
2600        double totalLength = Math.sqrt(distX * distX + distY * distY);
261  
262         //closeness is a double in the range [0,1] that represents
263         //how close to the target vertex the edge weight should be
264         //drawn (0 means "on the source vertex", 1 means "on the target
265         // vertex")
266         //weights of undirected edges should be drawn at 0.5 (in the middle of
267         // the edge)
268         double closeness;
2690        if (e instanceof DirectedEdge) {
2700            closeness = 0.73;
271         } else {
2720            closeness = 0.5;
273         }
274  
2750        int posX = (int) (x1 + (closeness) * distX);
2760        int posY = (int) (y1 + (closeness) * distY);
277  
2780        int LEN = 10;
2790        int xDisplacement = (int) (LEN * (-distY / totalLength));
2800        int yDisplacement = (int) (LEN * (distX / totalLength));
2810        g2d.drawString(label, posX + xDisplacement, posY + yDisplacement + mLineHeight / 2);
2820    }
283  
284     /**
285      * Draws an arrowhead on this edge in the direction from xsource,ysource to
286      * xend, yend
287      */
288     protected void drawArrowhead(Graphics2D g2d, Edge e, int xsource,
289             int ysource, int xdest, int ydest) {
290  
2910        if (mArrow == null) {
2920            mArrow = new Arrow(Arrow.CLASSIC, 7, 9);
293         }
294         
2950        if (mShouldDrawSelfLoops && self_loop.evaluate(e)) {
2960            mArrow.drawArrow(g2d, xsource - 10, ysource - 5, xsource, ysource, 15);
2970            return;
298         }
299         
3000        if (mDrawLightBoxes) {
3010            mArrow.drawArrow(g2d, xsource, ysource, xdest, ydest, 12);
302         } else {
3030            mArrow.drawArrow(g2d, xsource, ysource, xdest, ydest, 16);
304         }
305  
3060    }
307  
308     /**
309      * Draws the edge at the given width, then restores the previous stroke.
310      * Calls drawEdgeSimple to accomplish this task.
311      *
312      * @param edgeWidth
313      * the width of the stroke.
314      */
315     protected void drawEdge(float edgeWidth, Graphics g, Edge e, int x1,
316             int y1, int x2, int y2) {
3170        Graphics2D g2d = (Graphics2D) g;
318  
3190        Stroke previous = g2d.getStroke();
320  
321 // if (Math.floor(edgeWidth) == edgeWidth) {
322 // if (strokeTable[(int) edgeWidth] == null) {
323 // Stroke s = new BasicStroke(edgeWidth);
324 // strokeTable[(int) edgeWidth] = s;
325 // g2d.setStroke(strokeTable[(int) edgeWidth]);
326 // } else {
3270                g2d.setStroke(new BasicStroke(edgeWidth));
328 // }
329 // }
3300        drawEdgeSimple(g, e, x1, y1, x2, y2);
3310        g2d.setStroke(previous);
3320    }
333  
334     protected void drawEdgeSimple(Graphics g, Edge e, int x1, int y1, int x2,
335             int y2) {
336  
3370        if (mShouldDrawSelfLoops && self_loop.evaluate(e)) {
338             // self-loops
3390            g.drawOval(x1 - 15, y1 - 30, 30, 30);
340         } else {
3410            g.drawLine(x1, y1, x2, y2);
342         }
3430    }
344  
345     /**
346      * Manually sets the color of a Vertex's foreground (i.e. its text).
347      *
348      * @param vertexColor
349      */
350     public void setVertexForegroundColor(Color vertexColor) {
3510        this.vertexFGColor = vertexColor;
3520    }
353  
354     /**
355      * Manually sets the color of a picked Vertex's background (i.e. its field).
356      *
357      * @param vertexColor
358      */
359     public void setVertexPickedColor(Color vertexColor) {
3600        this.vertexPickedColor = vertexColor;
3610    }
362  
363     /**
364      * Manually sets the color of an unpicked Vertex's background (i.e. its
365      * field).
366      *
367      * @param vertexColor
368      */
369     public void setVertexBGColor(Color vertexColor) {
3700        this.vertexBGColor = vertexColor;
3710    }
372  
373     /**
374      * Finds the color of a vertex with a VertexColorFunction.
375      *
376      * @param vcf
377      */
378     public void setVertexColorFunction(VertexColorFunction vcf) {
3790        this.vertexColorFunction = vcf;
3800    }
381  
382     /**
383      * Simple label function returns the StringLabeller's notion of v's label.
384      * It may be sometimes useful to override this.
385      *
386      * @param v
387      * a vertex
388      * @return the label on the vertex.
389      */
390     protected String getLabel(Vertex v) {
3910        if (mStringLabeller == null) return "";
3920        String s = mStringLabeller.getLabel(v);
3930        if (s == null) {
3940            return "?";
395         } else {
3960            return s;
397         }
398     }
399  
400     /**
401      * Paints the vertex, using the settings above (VertexColors, etc). In this
402      * implmenetation, vertices are painted as filled squares with textual
403      * labels over the filled square.
404      */
405     public void paintVertex(Graphics g, Vertex v, int x, int y) {
4060        String label = getLabel(v);
4070        if (mDrawLightBoxes) {
4080            paintLightVertex(g, v, x, y, label);
4090            return;
410         }
411  
4120        Color fg = (vertexColorFunction == null) ? vertexFGColor
413                 : vertexColorFunction.getForeColor(v);
414  
4150        if (vertexColorFunction == null) {
4160            if (isPicked(v)) {
4170                g.setColor(vertexPickedColor);
418             } else
4190                g.setColor(vertexBGColor);
420         } else {
4210            g.setColor(vertexColorFunction.getBackColor(v));
422         }
423  
4240        g.fillRect(x - 8, y - 6, g.getFontMetrics().stringWidth(label) + 8, 16);
4250        g.setColor(fg);
4260        g.drawString(label, x - 4, y + 6);
4270    }
428  
429     /**
430      * @param g
431      * @param v
432      * @param x
433      * @param y
434      */
435     protected void paintLightVertex(Graphics g, Vertex v, int x, int y,
436             String label) {
437         Color bg;
4380        if (vertexColorFunction == null) {
4390            if (isPicked(v)) {
4400                bg = vertexPickedColor;
441             } else
4420                bg = vertexBGColor;
443         } else {
4440            bg = vertexColorFunction.getBackColor(v);
445         }
446  
4470        Color fg = (vertexColorFunction == null) ? vertexFGColor
448                 : vertexColorFunction.getForeColor(v);
449  
4500        g.setColor(fg);
4510        g.fillRect(x - 7, y - 7, 14, 14);
4520        g.setColor(bg);
4530        g.fillRect(x - 6, y - 6, 12, 12);
4540        if (label.equals("?")) return;
4550        g.setColor(fg);
4560        g.drawString(label, x + 8, y + 6 ); // + g.getFontMetrics().getHeight());
4570    }
458  
459 }

this report was generated by version 1.0.5 of jcoverage.
visit www.jcoverage.com for updates.

copyright © 2003, jcoverage ltd. all rights reserved.
Java is a trademark of Sun Microsystems, Inc. in the United States and other countries.