View Javadoc

1   /*
2    * Copyright (c) 2005, 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    * Created on Apr 16, 2005
9    */
10  
11  package edu.uci.ics.jung.visualization.transform;
12  
13  import java.awt.geom.AffineTransform;
14  import java.awt.geom.Point2D;
15  
16  import javax.swing.event.ChangeListener;
17  import javax.swing.event.EventListenerList;
18  
19  import edu.uci.ics.jung.visualization.transform.shape.ShapeTransformer;
20  import edu.uci.ics.jung.visualization.util.ChangeEventSupport;
21  import edu.uci.ics.jung.visualization.util.DefaultChangeEventSupport;
22  
23  /**
24   *
25   * Provides methods to mutate the AffineTransform used by AffineTransformer
26   * base class to map points from one coordinate system to
27   * another.
28   * 
29   * 
30   * @author Tom Nelson
31   *
32   * 
33   */
34  public class MutableAffineTransformer extends AffineTransformer 
35  implements MutableTransformer, ShapeTransformer, ChangeEventSupport {
36  
37      protected ChangeEventSupport changeSupport =
38          new DefaultChangeEventSupport(this);
39      
40      /**
41       * create an instance that does not transform points
42       *
43       */
44      public MutableAffineTransformer() {
45          // nothing left to do
46      }
47      /**
48       * Create an instance with the supplied transform
49       */
50      public MutableAffineTransformer(AffineTransform transform) {
51          super(transform);
52      }
53  
54      public String toString() {
55          return "MutableAffineTransformer using "+transform;
56      }
57      /**
58       * setter for the scale
59       * fires a PropertyChangeEvent with the AffineTransforms representing
60       * the previous and new values for scale and offset
61       * @param scalex
62       * @param scaley
63       */
64      public void scale(double scalex, double scaley, Point2D from) {
65          AffineTransform xf = AffineTransform.getTranslateInstance(from.getX(),from.getY());
66          xf.scale(scalex, scaley);
67          xf.translate(-from.getX(), -from.getY());
68          inverse = null;
69          transform.preConcatenate(xf);
70          fireStateChanged();
71      }
72      
73      /**
74       * setter for the scale
75       * fires a PropertyChangeEvent with the AffineTransforms representing
76       * the previous and new values for scale and offset
77       * @param scalex
78       * @param scaley
79       */
80      public void setScale(double scalex, double scaley, Point2D from) {
81          transform.setToIdentity();
82          scale(scalex, scaley, from);
83      }
84      
85      /**
86       * shears the transform by passed parameters
87       * @param shx x value to shear
88       * @param shy y value to shear
89       */
90      public void shear(double shx, double shy, Point2D from) {
91          inverse = null;
92          AffineTransform at = 
93              AffineTransform.getTranslateInstance(from.getX(), from.getY());
94          at.shear(shx, shy);
95          at.translate(-from.getX(), -from.getY());
96          transform.preConcatenate(at);
97          fireStateChanged();
98      }
99      
100     /**
101      * replace the Transform's translate x and y values
102      * with the passed values, leaving the scale values
103      * unchanged
104      * @param tx the x value 
105      * @param ty the y value
106      */
107     public void setTranslate(double tx, double ty) {
108         float scalex = (float) transform.getScaleX();
109         float scaley = (float) transform.getScaleY();
110         float shearx = (float) transform.getShearX();
111         float sheary = (float) transform.getShearY();
112         inverse = null;
113         transform.setTransform(scalex, 
114                 sheary, 
115                 shearx, 
116                 scaley,
117                 tx, ty);
118         fireStateChanged();
119     }
120     
121     /**
122      * Apply the passed values to the current Transform
123      * @param offsetx the x-value
124      * @param offsety the y-value
125      */
126     public void translate(double offsetx, double offsety) {
127         inverse = null;
128         transform.translate(offsetx, offsety);
129         fireStateChanged();
130     }
131     
132     /**
133      * preconcatenates the rotation at the supplied point with the current transform
134      */
135     public void rotate(double theta, Point2D from) {
136         AffineTransform rotate = 
137             AffineTransform.getRotateInstance(theta, from.getX(), from.getY());
138         inverse = null;
139         transform.preConcatenate(rotate);
140 
141         fireStateChanged();
142     }
143     
144     /**
145      * rotates the current transform at the supplied points
146      */
147     public void rotate(double radians, double x, double y) {
148         inverse = null;
149         transform.rotate(radians, x, y);
150         fireStateChanged();
151     }
152     
153     public void concatenate(AffineTransform xform) {
154         inverse = null;
155         transform.concatenate(xform);
156         fireStateChanged();
157         
158     }
159     public void preConcatenate(AffineTransform xform) {
160         inverse = null;
161         transform.preConcatenate(xform);
162         fireStateChanged();
163     }   
164 
165     
166     /**
167      * Adds a <code>ChangeListener</code>.
168      * @param l the listener to be added
169      */
170     public void addChangeListener(ChangeListener l) {
171         changeSupport.addChangeListener(l);
172     }
173     
174     /**
175      * Removes a ChangeListener.
176      * @param l the listener to be removed
177      */
178     public void removeChangeListener(ChangeListener l) {
179         changeSupport.removeChangeListener(l);
180     }
181     
182     /**
183      * Returns an array of all the <code>ChangeListener</code>s added
184      * with addChangeListener().
185      *
186      * @return all of the <code>ChangeListener</code>s added or an empty
187      *         array if no listeners have been added
188      */
189     public ChangeListener[] getChangeListeners() {
190         return changeSupport.getChangeListeners();
191     }
192 
193     /**
194      * Notifies all listeners that have registered interest for
195      * notification on this event type.  The event instance 
196      * is lazily created.
197      * @see EventListenerList
198      */
199     public void fireStateChanged() {
200         changeSupport.fireStateChanged();
201     }
202     
203     public void setToIdentity() {
204         inverse = null;
205         transform.setToIdentity();
206         fireStateChanged();
207     }
208 }