View Javadoc
1   /*
2    * Copyright (c) 2005, The JUNG Authors
3    * All rights reserved.
4    *
5    * This software is open-source under the BSD license; see either "license.txt"
6    * or https://github.com/jrtom/jung/blob/master/LICENSE for a description.
7    *
8    * Created on Aug 23, 2005
9    */
10  package edu.uci.ics.jung.visualization.renderers;
11  
12  import java.awt.Dimension;
13  import java.awt.Paint;
14  import java.awt.Rectangle;
15  import java.awt.Shape;
16  import java.awt.Stroke;
17  import java.awt.geom.AffineTransform;
18  import java.awt.geom.Point2D;
19  
20  import javax.swing.Icon;
21  import javax.swing.JComponent;
22  
23  import edu.uci.ics.jung.algorithms.layout.Layout;
24  import edu.uci.ics.jung.graph.Graph;
25  import edu.uci.ics.jung.graph.util.Context;
26  import edu.uci.ics.jung.visualization.Layer;
27  import edu.uci.ics.jung.visualization.RenderContext;
28  import edu.uci.ics.jung.visualization.transform.MutableTransformer;
29  import edu.uci.ics.jung.visualization.transform.MutableTransformerDecorator;
30  import edu.uci.ics.jung.visualization.transform.shape.GraphicsDecorator;
31  
32  public class BasicVertexRenderer<V,E> implements Renderer.Vertex<V,E> {
33  
34      public void paintVertex(RenderContext<V,E> rc, Layout<V,E> layout, V v) {
35      	Graph<V,E> graph = layout.getGraph();
36          if (rc.getVertexIncludePredicate().apply(Context.<Graph<V,E>,V>getInstance(graph,v))) {
37          	paintIconForVertex(rc, v, layout);
38          }
39      }
40      
41      /**
42       * Returns the vertex shape in view coordinates.
43       * @param rc the render context used for rendering the vertex
44       * @param v the vertex whose shape is to be returned
45       * @param layout the layout algorithm that provides coordinates for the vertex
46       * @param coords the x and y view coordinates
47       * @return the vertex shape in view coordinates
48       */
49      protected Shape prepareFinalVertexShape(RenderContext<V,E> rc, V v, 
50      		Layout<V,E> layout, int[] coords) {
51  
52          // get the shape to be rendered
53          Shape shape = rc.getVertexShapeTransformer().apply(v);
54          Point2D p = layout.apply(v);
55          p = rc.getMultiLayerTransformer().transform(Layer.LAYOUT, p);
56          float x = (float)p.getX();
57          float y = (float)p.getY();
58          coords[0] = (int)x;
59          coords[1] = (int)y;
60          // create a transform that translates to the location of
61          // the vertex to be rendered
62          AffineTransform xform = AffineTransform.getTranslateInstance(x,y);
63          // transform the vertex shape with xtransform
64          shape = xform.createTransformedShape(shape);
65          return shape;
66      }
67      
68      /**
69       * Paint <code>v</code>'s icon on <code>g</code> at <code>(x,y)</code>.
70       * 
71       * @param rc the render context used for rendering the vertex
72       * @param v the vertex to be painted
73       * @param layout the layout algorithm that provides coordinates for the vertex
74       */
75      protected void paintIconForVertex(RenderContext<V,E> rc, V v, Layout<V,E> layout) {
76          GraphicsDecorator g = rc.getGraphicsContext();
77          boolean vertexHit = true;
78          int[] coords = new int[2];
79          Shape shape = prepareFinalVertexShape(rc, v, layout, coords);
80          vertexHit = vertexHit(rc, shape);
81  
82          if (vertexHit) {
83          	if(rc.getVertexIconTransformer() != null) {
84          		Icon icon = rc.getVertexIconTransformer().apply(v);
85          		if(icon != null) {
86          		
87             			g.draw(icon, rc.getScreenDevice(), shape, coords[0], coords[1]);
88  
89          		} else {
90          			paintShapeForVertex(rc, v, shape);
91          		}
92          	} else {
93          		paintShapeForVertex(rc, v, shape);
94          	}
95          }
96      }
97      
98      protected boolean vertexHit(RenderContext<V,E> rc, Shape s) {
99          JComponent vv = rc.getScreenDevice();
100         Rectangle deviceRectangle = null;
101         if(vv != null) {
102             Dimension d = vv.getSize();
103             deviceRectangle = new Rectangle(
104                     0,0,
105                     d.width,d.height);
106         }
107         MutableTransformer vt = rc.getMultiLayerTransformer().getTransformer(Layer.VIEW);
108         if(vt instanceof MutableTransformerDecorator) {
109         	vt = ((MutableTransformerDecorator)vt).getDelegate();
110         }
111         return vt.transform(s).intersects(deviceRectangle);
112     }
113 
114     protected void paintShapeForVertex(RenderContext<V,E> rc, V v, Shape shape) {
115         GraphicsDecorator g = rc.getGraphicsContext();
116         Paint oldPaint = g.getPaint();
117         Paint fillPaint = rc.getVertexFillPaintTransformer().apply(v);
118         if(fillPaint != null) {
119             g.setPaint(fillPaint);
120             g.fill(shape);
121             g.setPaint(oldPaint);
122         }
123         Paint drawPaint = rc.getVertexDrawPaintTransformer().apply(v);
124         if(drawPaint != null) {
125         	g.setPaint(drawPaint);
126         	Stroke oldStroke = g.getStroke();
127         	Stroke stroke = rc.getVertexStrokeTransformer().apply(v);
128         	if(stroke != null) {
129         		g.setStroke(stroke);
130         	}
131         	g.draw(shape);
132         	g.setPaint(oldPaint);
133         	g.setStroke(oldStroke);
134         }
135     }
136 }