1 | /* |
2 | * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. |
3 | * |
4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions |
6 | * are met: |
7 | * |
8 | * -Redistributions of source code must retain the above copyright |
9 | * notice, this list of conditions and the following disclaimer. |
10 | * |
11 | * -Redistribution in binary form must reproduct the above copyright |
12 | * notice, this list of conditions and the following disclaimer in |
13 | * the documentation and/or other materials provided with the distribution. |
14 | * |
15 | * Neither the name of Sun Microsystems, Inc. or the names of contributors |
16 | * may be used to endorse or promote products derived from this software |
17 | * without specific prior written permission. |
18 | * |
19 | * This software is provided "AS IS," without a warranty of any kind. ALL |
20 | * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING |
21 | * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE |
22 | * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT |
23 | * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT |
24 | * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS |
25 | * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST |
26 | * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, |
27 | * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY |
28 | * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN |
29 | * IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. |
30 | * |
31 | * You acknowledge that Software is not designed, licensed or intended for |
32 | * use in the design, construction, operation or maintenance of any nuclear |
33 | * facility. |
34 | */ |
35 | |
36 | /* |
37 | * @(#)BezierAnimationPanel.java 1.12 03/03/12 |
38 | */ |
39 | |
40 | |
41 | import javax.swing.*; |
42 | import javax.swing.event.*; |
43 | import javax.swing.text.*; |
44 | import javax.swing.border.*; |
45 | import javax.swing.colorchooser.*; |
46 | import javax.swing.filechooser.*; |
47 | import javax.accessibility.*; |
48 | |
49 | import java.awt.*; |
50 | import java.awt.font.*; |
51 | import java.awt.geom.*; |
52 | import java.awt.image.*; |
53 | import java.awt.event.*; |
54 | |
55 | /** |
56 | * BezierAnimationPanel |
57 | * |
58 | * @version 1.12 03/12/03 |
59 | * @author Jim Graham |
60 | * @author Jeff Dinkins (removed dynamic setting changes, made swing friendly) |
61 | */ |
62 | class BezierAnimationPanel extends JPanel implements Runnable { |
63 | |
64 | Color backgroundColor = new Color(0, 0, 153); |
65 | Color outerColor = new Color(255, 255, 255); |
66 | Color gradientColorA = new Color(255, 0, 101); |
67 | Color gradientColorB = new Color(255, 255, 0); |
68 | |
69 | boolean bgChanged = false; |
70 | |
71 | GradientPaint gradient = null; |
72 | |
73 | public final int NUMPTS = 6; |
74 | |
75 | float animpts[] = new float[NUMPTS * 2]; |
76 | |
77 | float deltas[] = new float[NUMPTS * 2]; |
78 | |
79 | float staticpts[] = { |
80 | 50.0f, 0.0f, |
81 | 150.0f, 0.0f, |
82 | 200.0f, 75.0f, |
83 | 150.0f, 150.0f, |
84 | 50.0f, 150.0f, |
85 | 0.0f, 75.0f, |
86 | }; |
87 | |
88 | float movepts[] = new float[staticpts.length]; |
89 | |
90 | BufferedImage img; |
91 | |
92 | Rectangle bounds = null; |
93 | |
94 | Thread anim; |
95 | |
96 | /** |
97 | * BezierAnimationPanel Constructor |
98 | */ |
99 | public BezierAnimationPanel() { |
100 | addHierarchyListener( |
101 | new HierarchyListener() { |
102 | public void hierarchyChanged(HierarchyEvent e) { |
103 | if(isShowing()) { |
104 | start(); |
105 | } else { |
106 | stop(); |
107 | } |
108 | } |
109 | } |
110 | ); |
111 | setBackground(getBackgroundColor()); |
112 | } |
113 | |
114 | public boolean isOpaque() { |
115 | return true; |
116 | } |
117 | |
118 | public Color getGradientColorA() { |
119 | return gradientColorA; |
120 | } |
121 | |
122 | public void setGradientColorA(Color c) { |
123 | if(c != null) { |
124 | gradientColorA = c; |
125 | } |
126 | } |
127 | |
128 | public Color getGradientColorB() { |
129 | return gradientColorB; |
130 | } |
131 | |
132 | public void setGradientColorB(Color c) { |
133 | if(c != null) { |
134 | gradientColorB = c; |
135 | } |
136 | } |
137 | |
138 | public Color getOuterColor() { |
139 | return outerColor; |
140 | } |
141 | |
142 | public void setOuterColor(Color c) { |
143 | if(c != null) { |
144 | outerColor = c; |
145 | } |
146 | } |
147 | |
148 | public Color getBackgroundColor() { |
149 | return backgroundColor; |
150 | } |
151 | |
152 | public void setBackgroundColor(Color c) { |
153 | if(c != null) { |
154 | backgroundColor = c; |
155 | setBackground(c); |
156 | bgChanged = true; |
157 | } |
158 | } |
159 | |
160 | public void start() { |
161 | Dimension size = getSize(); |
162 | for (int i = 0; i < animpts.length; i += 2) { |
163 | animpts[i + 0] = (float) (Math.random() * size.width); |
164 | animpts[i + 1] = (float) (Math.random() * size.height); |
165 | deltas[i + 0] = (float) (Math.random() * 4.0 + 2.0); |
166 | deltas[i + 1] = (float) (Math.random() * 4.0 + 2.0); |
167 | if (animpts[i + 0] > size.width / 6.0f) { |
168 | deltas[i + 0] = -deltas[i + 0]; |
169 | } |
170 | if (animpts[i + 1] > size.height / 6.0f) { |
171 | deltas[i + 1] = -deltas[i + 1]; |
172 | } |
173 | } |
174 | anim = new Thread(this); |
175 | anim.setPriority(Thread.MIN_PRIORITY); |
176 | anim.start(); |
177 | } |
178 | |
179 | public synchronized void stop() { |
180 | anim = null; |
181 | notify(); |
182 | } |
183 | |
184 | public void animate(float[] pts, float[] deltas, int index, int limit) { |
185 | float newpt = pts[index] + deltas[index]; |
186 | if (newpt <= 0) { |
187 | newpt = -newpt; |
188 | deltas[index] = (float) (Math.random() * 3.0 + 2.0); |
189 | } else if (newpt >= (float) limit) { |
190 | newpt = 2.0f * limit - newpt; |
191 | deltas[index] = - (float) (Math.random() * 3.0 + 2.0); |
192 | } |
193 | pts[index] = newpt; |
194 | } |
195 | |
196 | public void run() { |
197 | Thread me = Thread.currentThread(); |
198 | while (getSize().width <= 0) { |
199 | try { |
200 | anim.sleep(500); |
201 | } catch (InterruptedException e) { |
202 | return; |
203 | } |
204 | } |
205 | |
206 | Graphics2D g2d = null; |
207 | Graphics2D BufferG2D = null; |
208 | Graphics2D ScreenG2D = null; |
209 | BasicStroke solid = new BasicStroke(9.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 9.0f); |
210 | GeneralPath gp = new GeneralPath(GeneralPath.WIND_NON_ZERO); |
211 | int rule = AlphaComposite.SRC_OVER; |
212 | AlphaComposite opaque = AlphaComposite.SrcOver; |
213 | AlphaComposite blend = AlphaComposite.getInstance(rule, 0.9f); |
214 | AlphaComposite set = AlphaComposite.Src; |
215 | int frame = 0; |
216 | int frametmp = 0; |
217 | Dimension oldSize = getSize(); |
218 | Shape clippath = null; |
219 | while (anim == me) { |
220 | Dimension size = getSize(); |
221 | if (size.width != oldSize.width || size.height != oldSize.height) { |
222 | img = null; |
223 | clippath = null; |
224 | if (BufferG2D != null) { |
225 | BufferG2D.dispose(); |
226 | BufferG2D = null; |
227 | } |
228 | if (ScreenG2D != null) { |
229 | ScreenG2D.dispose(); |
230 | ScreenG2D = null; |
231 | } |
232 | } |
233 | oldSize = size; |
234 | |
235 | if (img == null) { |
236 | img = (BufferedImage) createImage(size.width, size.height); |
237 | } |
238 | |
239 | if (BufferG2D == null) { |
240 | BufferG2D = img.createGraphics(); |
241 | BufferG2D.setRenderingHint(RenderingHints.KEY_RENDERING, |
242 | RenderingHints.VALUE_RENDER_DEFAULT); |
243 | BufferG2D.setClip(clippath); |
244 | } |
245 | g2d = BufferG2D; |
246 | |
247 | float[] ctrlpts; |
248 | for (int i = 0; i < animpts.length; i += 2) { |
249 | animate(animpts, deltas, i + 0, size.width); |
250 | animate(animpts, deltas, i + 1, size.height); |
251 | } |
252 | ctrlpts = animpts; |
253 | int len = ctrlpts.length; |
254 | gp.reset(); |
255 | int dir = 0; |
256 | float prevx = ctrlpts[len - 2]; |
257 | float prevy = ctrlpts[len - 1]; |
258 | float curx = ctrlpts[0]; |
259 | float cury = ctrlpts[1]; |
260 | float midx = (curx + prevx) / 2.0f; |
261 | float midy = (cury + prevy) / 2.0f; |
262 | gp.moveTo(midx, midy); |
263 | for (int i = 2; i <= ctrlpts.length; i += 2) { |
264 | float x1 = (midx + curx) / 2.0f; |
265 | float y1 = (midy + cury) / 2.0f; |
266 | prevx = curx; |
267 | prevy = cury; |
268 | if (i < ctrlpts.length) { |
269 | curx = ctrlpts[i + 0]; |
270 | cury = ctrlpts[i + 1]; |
271 | } else { |
272 | curx = ctrlpts[0]; |
273 | cury = ctrlpts[1]; |
274 | } |
275 | midx = (curx + prevx) / 2.0f; |
276 | midy = (cury + prevy) / 2.0f; |
277 | float x2 = (prevx + midx) / 2.0f; |
278 | float y2 = (prevy + midy) / 2.0f; |
279 | gp.curveTo(x1, y1, x2, y2, midx, midy); |
280 | } |
281 | gp.closePath(); |
282 | |
283 | g2d.setComposite(set); |
284 | g2d.setBackground(backgroundColor); |
285 | g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, |
286 | RenderingHints.VALUE_ANTIALIAS_OFF); |
287 | |
288 | if(bgChanged || bounds == null) { |
289 | bounds = new Rectangle(0, 0, getWidth(), getHeight()); |
290 | bgChanged = false; |
291 | } |
292 | // g2d.clearRect(bounds.x-5, bounds.y-5, bounds.x + bounds.width + 5, bounds.y + bounds.height + 5); |
293 | g2d.clearRect(0, 0, getWidth(), getHeight()); |
294 | |
295 | g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, |
296 | RenderingHints.VALUE_ANTIALIAS_ON); |
297 | g2d.setColor(outerColor); |
298 | g2d.setComposite(opaque); |
299 | g2d.setStroke(solid); |
300 | g2d.draw(gp); |
301 | g2d.setPaint(gradient); |
302 | |
303 | if(!bgChanged) { |
304 | bounds = gp.getBounds(); |
305 | } else { |
306 | bounds = new Rectangle(0, 0, getWidth(), getHeight()); |
307 | bgChanged = false; |
308 | } |
309 | gradient = new GradientPaint(bounds.x, bounds.y, gradientColorA, |
310 | bounds.x + bounds.width, bounds.y + bounds.height, |
311 | gradientColorB, true); |
312 | g2d.setComposite(blend); |
313 | g2d.fill(gp); |
314 | |
315 | if (g2d == BufferG2D) { |
316 | repaint(); |
317 | } |
318 | ++frame; |
319 | Thread.yield(); |
320 | } |
321 | if (g2d != null) { |
322 | g2d.dispose(); |
323 | } |
324 | } |
325 | |
326 | public void paint(Graphics g) { |
327 | synchronized (this) { |
328 | Graphics2D g2d = (Graphics2D) g; |
329 | if (img != null) { |
330 | int imgw = img.getWidth(); |
331 | int imgh = img.getHeight(); |
332 | g2d.setComposite(AlphaComposite.Src); |
333 | g2d.drawImage(img, null, 0, 0); |
334 | } |
335 | } |
336 | } |
337 | } |