View Javadoc
1   /*
2    * Created on Apr 8, 2005
3    *
4    * Copyright (c) 2004, The JUNG Authors 
5    *
6    * All rights reserved.
7    *
8    * This software is open-source under the BSD license; see either
9    * "license.txt" or
10   * https://github.com/jrtom/jung/blob/master/LICENSE for a description.
11   */
12  package edu.uci.ics.jung.visualization.decorators;
13  
14  import java.awt.Color;
15  import java.awt.GradientPaint;
16  import java.awt.Paint;
17  import java.awt.geom.Point2D;
18  
19  import com.google.common.base.Function;
20  import com.google.common.base.Predicate;
21  
22  import edu.uci.ics.jung.algorithms.layout.Layout;
23  import edu.uci.ics.jung.algorithms.util.SelfLoopEdgePredicate;
24  import edu.uci.ics.jung.graph.Graph;
25  import edu.uci.ics.jung.graph.util.Context;
26  import edu.uci.ics.jung.graph.util.EdgeType;
27  import edu.uci.ics.jung.graph.util.Pair;
28  import edu.uci.ics.jung.visualization.Layer;
29  import edu.uci.ics.jung.visualization.VisualizationViewer;
30  import edu.uci.ics.jung.visualization.transform.BidirectionalTransformer;
31  
32  /**
33   * Creates <code>GradientPaint</code> instances which can be used
34   * to paint an <code>Edge</code>.  For <code>DirectedEdge</code>s, 
35   * the color will blend from <code>c1</code> (source) to 
36   * <code>c2</code> (destination); for <code>UndirectedEdge</code>s,
37   * the color will be <code>c1</code> at each end and <code>c2</code>
38   * in the middle.
39   * 
40   * @author Joshua O'Madadhain
41   */
42  public class GradientEdgePaintTransformer<V, E> 
43  	implements Function<E,Paint>
44  {
45      protected Color c1;
46      protected Color c2;
47      protected VisualizationViewer<V,E> vv;
48      protected BidirectionalTransformer transformer;
49      protected Predicate<Context<Graph<V,E>,E>> selfLoop = new SelfLoopEdgePredicate<V,E>();
50  
51      public GradientEdgePaintTransformer(Color c1, Color c2, 
52              VisualizationViewer<V,E> vv)
53      {
54          this.c1 = c1;
55          this.c2 = c2;
56          this.vv = vv;
57          this.transformer = vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT);
58      }
59      
60      public Paint apply(E e)
61      {
62          Layout<V, E> layout = vv.getGraphLayout();
63          Pair<V> p = layout.getGraph().getEndpoints(e);
64          V b = p.getFirst();
65          V f = p.getSecond();
66          Point2D pb = transformer.transform(layout.apply(b));
67          Point2D pf = transformer.transform(layout.apply(f));
68          float xB = (float) pb.getX();
69          float yB = (float) pb.getY();
70          float xF = (float) pf.getX();
71          float yF = (float) pf.getY();
72          if ((layout.getGraph().getEdgeType(e)) == EdgeType.UNDIRECTED)  {
73              xF = (xF + xB) / 2;
74              yF = (yF + yB) / 2;
75          } 
76          if(selfLoop.apply(Context.<Graph<V,E>,E>getInstance(layout.getGraph(), e))) {
77          	yF += 50;
78          	xF += 50;
79          }
80  
81          return new GradientPaint(xB, yB, getColor1(e), xF, yF, getColor2(e), true);
82      }
83      
84      /**
85       * Returns <code>c1</code>.  Subclasses may override
86       * this method to enable more complex behavior (e.g., for
87       * picked edges).
88       * @param e the edge for which a color is to be retrieved
89       * @return the constructor-supplied color {@code c1}
90       */
91      protected Color getColor1(E e)
92      {
93          return c1;
94      }
95  
96      /**
97       * Returns <code>c2</code>.  Subclasses may override
98       * this method to enable more complex behavior (e.g., for
99       * picked edges).
100      * @param e the edge for which a color is to be retrieved
101      * @return the constructor-supplied color {@code c2}
102      */
103     protected Color getColor2(E e)
104     {
105         return c2;
106     }
107 }