/Users/lyon/j4p/src/j2d/graphics/AffineImagePanel.java

1    package j2d.graphics; 
2     
3    import gui.ClosableJFrame; 
4    import gui.run.RunSlider; 
5    import j2d.ImageUtils; 
6     
7    import javax.swing.*; 
8    import java.awt.*; 
9    import java.awt.geom.AffineTransform; 
10   import java.awt.geom.GeneralPath; 
11   import java.awt.geom.Point2D; 
12    
13   public class AffineImagePanel extends JPanel { 
14       double theta = 30; 
15       Point2D location = new Point2D.Float(20, 30); 
16       Point2D scale = new Point2D.Float(0.5f, 0.5f); 
17       Point2D shear = new Point2D.Float(.2f,0f); 
18       Image image = ImageUtils.getImage(); 
19    
20       public static void main(String args[]) { 
21           new AffineImagePanel(); 
22       } 
23    
24       AffineImagePanel() { 
25           displayAffineImageFrame(); 
26       } 
27    
28       public void displayAffineImageFrame() { 
29           ClosableJFrame cf = new ClosableJFrame(); 
30           Container c = cf.getContentPane(); 
31           c.setLayout(new BorderLayout()); 
32           c.add(this, BorderLayout.CENTER); 
33           c.add(getControlPanel(), BorderLayout.SOUTH); 
34           cf.setSize(200, 200); 
35           cf.show(); 
36       } 
37    
38       public JPanel getControlPanel() { 
39           JPanel jp = new JPanel(); 
40           jp.setLayout(new GridLayout(0, 1)); 
41           jp.add(new RunSlider(0, 360) { 
42               public void run() { 
43                   rotate(getValue()); 
44               } 
45           }); 
46           jp.add(new RunSlider(0, 100) { 
47               public void run() { 
48                   translateX(getValue()); 
49               } 
50           }); 
51           jp.add(new RunSlider(0, 100) { 
52               public void run() { 
53                   translateY(getValue()); 
54               } 
55           }); 
56           jp.add(new RunSlider(-100, 100) { 
57               public void run() { 
58                   scaleX(getValue() / 100.0); 
59               } 
60           }); 
61           jp.add(new RunSlider(-100, 100) { 
62               public void run() { 
63                   scaleY(getValue() / 100.0); 
64               } 
65           }); 
66           jp.add(new RunSlider(-100, 100) { 
67               public void run() { 
68                   shearX(getValue() / 100.0); 
69               } 
70           }); 
71           jp.add(new RunSlider(-100, 100) { 
72               public void run() { 
73                   shearY(getValue() / 100.0); 
74               } 
75           }); 
76           return jp; 
77       } 
78    
79       public void translateX(int x) { 
80           location.setLocation(x, location.getY()); 
81           repaint(); 
82       } 
83    
84       public void translateY(int y) { 
85           location.setLocation(location.getX(), y); 
86           repaint(); 
87       } 
88    
89       public void scaleX(double sx) { 
90           scale.setLocation(sx, location.getY()); 
91           repaint(); 
92       } 
93    
94       public void scaleY(double sy) { 
95           scale.setLocation(location.getX(), sy); 
96           repaint(); 
97       } 
98    
99       public void shearX(double sx) { 
100          shear.setLocation(sx, location.getY()); 
101          repaint(); 
102      } 
103   
104      public void shearY(double sy) { 
105          shear.setLocation(location.getX(), sy); 
106          repaint(); 
107      } 
108   
109      public void rotate(double radians) { 
110          theta = radians; 
111          repaint(); 
112      } 
113   
114      public void paint(Graphics g) { 
115          Graphics2D g2 = (Graphics2D) g; 
116          drawImage(g2, scale.getX(), scale.getY(), location, theta); 
117      } 
118   
119      /** 
120       * Rotate the arrow using degrees for the angle. 
121       * 
122       * @param g2 
123       * @param sx 
124       * @param sy 
125       * @param location 
126       * @param angle 
127       */ 
128      private void drawArrow(Graphics2D g2, 
129                             float sx, float sy, 
130                             Point2D location, 
131                             double angle) { 
132          GeneralPath gp = getArrow(); 
133          //erase(g2, gp); 
134          setUpAffineTransform(location, sx, sy, g2, angle); 
135          g2.draw(gp); 
136      } 
137   
138      private void drawImage(Graphics2D g2, 
139                             double sx, double sy, 
140                             Point2D location, 
141                             double angle) { 
142          Dimension d = getSize(); 
143          g2.fillRect(0, 0, d.width, d.height); 
144   
145          g2.translate(location.getX(), location.getY()); 
146          g2.rotate(angle*Math.PI/180.0); 
147          g2.shear(shear.getX(), shear.getY()); 
148          g2.scale(scale.getX(), scale.getY()); 
149          g2.drawImage(image, 0, 0, this); 
150      } 
151   
152   
153      private void setUpAffineTransform(Point2D location, float sx, float sy, Graphics2D g2, double angle) { 
154          AffineTransform at = new AffineTransform(); 
155          //at.shear(shear.getX(), shear.getY()); 
156          at.setToTranslation(location.getX(), location.getY()); 
157          at.scale(sx, sy); 
158   
159          at.rotate(angle * Math.PI / 180, 10, 10); 
160   
161          g2.setTransform(at); 
162   
163          //g2.setTransform(at); 
164      } 
165   
166   
167      private void erase(Graphics2D g2, GeneralPath gp) { 
168          g2.setXORMode(getBackground()); 
169          g2.draw(gp); 
170          g2.setXORMode(getForeground()); 
171      } 
172   
173   
174      private GeneralPath getArrow() { 
175          GeneralPath gp = new GeneralPath(GeneralPath.WIND_EVEN_ODD); 
176          gp.moveTo(0f, -15f); 
177          gp.lineTo(10f, 5f); 
178          gp.lineTo(5f, 5f); 
179          gp.lineTo(5f, 15f); 
180          gp.lineTo(-5, 15f); 
181          gp.lineTo(-5f, 5f); 
182          gp.lineTo(-10f, 5f); 
183          gp.closePath(); 
184          return gp; 
185      } 
186  } 
187