|
1 /* |
|
2 * |
|
3 * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. |
|
4 * |
|
5 * Redistribution and use in source and binary forms, with or without |
|
6 * modification, are permitted provided that the following conditions |
|
7 * are met: |
|
8 * |
|
9 * - Redistributions of source code must retain the above copyright |
|
10 * notice, this list of conditions and the following disclaimer. |
|
11 * |
|
12 * - Redistributions in binary form must reproduce the above copyright |
|
13 * notice, this list of conditions and the following disclaimer in the |
|
14 * documentation and/or other materials provided with the distribution. |
|
15 * |
|
16 * - Neither the name of Oracle nor the names of its |
|
17 * contributors may be used to endorse or promote products derived |
|
18 * from this software without specific prior written permission. |
|
19 * |
|
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS |
|
21 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
|
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
|
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
|
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
|
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
|
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
|
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
|
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
31 */ |
|
32 package java2d.demos.Composite; |
|
33 |
|
34 |
|
35 import static java.awt.Color.BLACK; |
|
36 import static java.awt.Color.BLUE; |
|
37 import static java.awt.Color.CYAN; |
|
38 import static java.awt.Color.GREEN; |
|
39 import static java.awt.Color.LIGHT_GRAY; |
|
40 import static java.awt.Color.MAGENTA; |
|
41 import static java.awt.Color.ORANGE; |
|
42 import static java.awt.Color.PINK; |
|
43 import static java.awt.Color.RED; |
|
44 import static java.awt.Color.WHITE; |
|
45 import static java.awt.Color.YELLOW; |
|
46 import java.awt.AlphaComposite; |
|
47 import java.awt.BasicStroke; |
|
48 import java.awt.BorderLayout; |
|
49 import java.awt.Color; |
|
50 import java.awt.Component; |
|
51 import java.awt.Dimension; |
|
52 import java.awt.Font; |
|
53 import java.awt.FontMetrics; |
|
54 import java.awt.GradientPaint; |
|
55 import java.awt.Graphics2D; |
|
56 import java.awt.Image; |
|
57 import java.awt.Paint; |
|
58 import java.awt.Rectangle; |
|
59 import java.awt.Shape; |
|
60 import java.awt.TexturePaint; |
|
61 import java.awt.geom.Arc2D; |
|
62 import java.awt.geom.CubicCurve2D; |
|
63 import java.awt.geom.Ellipse2D; |
|
64 import java.awt.geom.GeneralPath; |
|
65 import java.awt.geom.QuadCurve2D; |
|
66 import java.awt.geom.Rectangle2D; |
|
67 import java.awt.geom.RoundRectangle2D; |
|
68 import java.awt.image.BufferedImage; |
|
69 import java.util.ArrayList; |
|
70 import java.util.List; |
|
71 import java2d.AnimatingControlsSurface; |
|
72 import java2d.CustomControls; |
|
73 import javax.swing.Box; |
|
74 import javax.swing.BoxLayout; |
|
75 import javax.swing.JSlider; |
|
76 import javax.swing.JToolBar; |
|
77 import javax.swing.SwingConstants; |
|
78 import javax.swing.border.EtchedBorder; |
|
79 import javax.swing.border.TitledBorder; |
|
80 import javax.swing.event.ChangeEvent; |
|
81 import javax.swing.event.ChangeListener; |
|
82 |
|
83 |
|
84 /** |
|
85 * Animation of compositing shapes, text and images fading in and out. |
|
86 */ |
|
87 @SuppressWarnings("serial") |
|
88 public final class FadeAnim extends AnimatingControlsSurface { |
|
89 |
|
90 private static final TexturePaint texturePaint; |
|
91 |
|
92 static { |
|
93 int w = 10; |
|
94 int h = 10; |
|
95 BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); |
|
96 Graphics2D gi = bi.createGraphics(); |
|
97 Color oc = BLUE; |
|
98 Color ic = GREEN; |
|
99 gi.setPaint(new GradientPaint(0, 0, oc, w * .35f, h * .35f, ic)); |
|
100 gi.fillRect(0, 0, w / 2, h / 2); |
|
101 gi.setPaint(new GradientPaint(w, 0, oc, w * .65f, h * .35f, ic)); |
|
102 gi.fillRect(w / 2, 0, w / 2, h / 2); |
|
103 gi.setPaint(new GradientPaint(0, h, oc, w * .35f, h * .65f, ic)); |
|
104 gi.fillRect(0, h / 2, w / 2, h / 2); |
|
105 gi.setPaint(new GradientPaint(w, h, oc, w * .65f, h * .65f, ic)); |
|
106 gi.fillRect(w / 2, h / 2, w / 2, h / 2); |
|
107 texturePaint = new TexturePaint(bi, new Rectangle(0, 0, w, h)); |
|
108 } |
|
109 private static BasicStroke bs = new BasicStroke(6); |
|
110 private static Font fonts[] = { |
|
111 new Font(Font.SERIF, Font.PLAIN, 64), |
|
112 new Font(Font.SERIF, Font.BOLD | Font.ITALIC, 24), |
|
113 new Font(Font.MONOSPACED, Font.BOLD, 36), |
|
114 new Font(Font.SANS_SERIF, Font.BOLD | Font.ITALIC, 48), |
|
115 new Font(Font.SANS_SERIF, Font.PLAIN, 52) }; |
|
116 private static String strings[] = { |
|
117 "Alpha", "Composite", "Src", "SrcOver", |
|
118 "SrcIn", "SrcOut", "Clear", "DstOver", "DstIn" }; |
|
119 private static String imgs[] = { |
|
120 "jumptojavastrip.png", "duke.png", "star7.png" }; |
|
121 private static Paint paints[] = { |
|
122 RED, BLUE, GREEN, MAGENTA, |
|
123 ORANGE, PINK, CYAN, texturePaint, |
|
124 YELLOW, LIGHT_GRAY, WHITE }; |
|
125 private List<ObjectData> objects = new ArrayList<ObjectData>(20); |
|
126 private int numShapes, numStrings, numImages; |
|
127 |
|
128 public FadeAnim() { |
|
129 setBackground(BLACK); |
|
130 setStrings(2); |
|
131 setImages(3); |
|
132 setShapes(8); |
|
133 setControls(new Component[] { new DemoControls(this) }); |
|
134 setConstraints(new String[] { BorderLayout.EAST }); |
|
135 } |
|
136 |
|
137 public void setImages(int num) { |
|
138 |
|
139 if (num < numImages) { |
|
140 List<ObjectData> images = new ArrayList<ObjectData>(objects.size()); |
|
141 for (ObjectData obj : objects) { |
|
142 if (obj.object instanceof Image) { |
|
143 images.add(obj); |
|
144 } |
|
145 } |
|
146 objects.removeAll(images.subList(num, images.size())); |
|
147 } else { |
|
148 Dimension d = getSize(); |
|
149 for (int i = numImages; i < num; i++) { |
|
150 Object obj = getImage(imgs[i % imgs.length]); |
|
151 if (imgs[i % imgs.length].equals("jumptojavastrip.png")) { |
|
152 int iw = ((Image) obj).getWidth(null); |
|
153 int ih = ((Image) obj).getHeight(null); |
|
154 BufferedImage bimage = new BufferedImage(iw, ih, |
|
155 BufferedImage.TYPE_INT_RGB); |
|
156 bimage.createGraphics().drawImage((Image) obj, 0, 0, null); |
|
157 obj = bimage; |
|
158 } |
|
159 ObjectData od = new ObjectData(obj, BLACK); |
|
160 od.reset(d.width, d.height); |
|
161 objects.add(od); |
|
162 } |
|
163 } |
|
164 numImages = num; |
|
165 } |
|
166 |
|
167 public void setStrings(int num) { |
|
168 |
|
169 if (num < numStrings) { |
|
170 List<ObjectData> textDatas = new ArrayList<ObjectData>( |
|
171 objects.size()); |
|
172 //for (int i = 0; i < objects.size(); i++) { |
|
173 for (ObjectData obj : objects) { |
|
174 if (obj.object instanceof TextData) { |
|
175 textDatas.add(obj); |
|
176 } |
|
177 } |
|
178 objects.removeAll(textDatas.subList(num, textDatas.size())); |
|
179 } else { |
|
180 Dimension d = getSize(); |
|
181 for (int i = numStrings; i < num; i++) { |
|
182 int j = i % fonts.length; |
|
183 int k = i % strings.length; |
|
184 Object obj = new TextData(strings[k], fonts[j], this); |
|
185 ObjectData od = new ObjectData(obj, paints[i % paints.length]); |
|
186 od.reset(d.width, d.height); |
|
187 objects.add(od); |
|
188 } |
|
189 } |
|
190 numStrings = num; |
|
191 } |
|
192 |
|
193 public void setShapes(int num) { |
|
194 |
|
195 if (num < numShapes) { |
|
196 List<ObjectData> shapes = new ArrayList<ObjectData>(objects.size()); |
|
197 //for (int i = 0; i < objects.size(); i++) { |
|
198 for (ObjectData obj : objects) { |
|
199 if (obj.object instanceof Shape) { |
|
200 shapes.add(obj); |
|
201 } |
|
202 } |
|
203 objects.removeAll(shapes.subList(num, shapes.size())); |
|
204 } else { |
|
205 Dimension d = getSize(); |
|
206 for (int i = numShapes; i < num; i++) { |
|
207 Object obj = null; |
|
208 switch (i % 7) { |
|
209 case 0: |
|
210 obj = new GeneralPath(); |
|
211 break; |
|
212 case 1: |
|
213 obj = new Rectangle2D.Double(); |
|
214 break; |
|
215 case 2: |
|
216 obj = new Ellipse2D.Double(); |
|
217 break; |
|
218 case 3: |
|
219 obj = new Arc2D.Double(); |
|
220 break; |
|
221 case 4: |
|
222 obj = new RoundRectangle2D.Double(); |
|
223 break; |
|
224 case 5: |
|
225 obj = new CubicCurve2D.Double(); |
|
226 break; |
|
227 case 6: |
|
228 obj = new QuadCurve2D.Double(); |
|
229 break; |
|
230 } |
|
231 ObjectData od = new ObjectData(obj, paints[i % paints.length]); |
|
232 od.reset(d.width, d.height); |
|
233 objects.add(od); |
|
234 } |
|
235 } |
|
236 numShapes = num; |
|
237 } |
|
238 |
|
239 @Override |
|
240 public void reset(int w, int h) { |
|
241 for (int i = 0; i < objects.size(); i++) { |
|
242 objects.get(i).reset(w, h); |
|
243 } |
|
244 } |
|
245 |
|
246 @Override |
|
247 public void step(int w, int h) { |
|
248 for (int i = 0; i < objects.size(); i++) { |
|
249 objects.get(i).step(w, h); |
|
250 } |
|
251 } |
|
252 |
|
253 @Override |
|
254 public void render(int w, int h, Graphics2D g2) { |
|
255 for (int i = 0; i < objects.size(); i++) { |
|
256 ObjectData od = objects.get(i); |
|
257 AlphaComposite ac = AlphaComposite.getInstance( |
|
258 AlphaComposite.SRC_OVER, od.alpha); |
|
259 g2.setComposite(ac); |
|
260 g2.setPaint(od.paint); |
|
261 g2.translate(od.x, od.y); |
|
262 |
|
263 if (od.object instanceof Image) { |
|
264 g2.drawImage((Image) od.object, 0, 0, this); |
|
265 } else if (od.object instanceof TextData) { |
|
266 g2.setFont(((TextData) od.object).font); |
|
267 g2.drawString(((TextData) od.object).string, 0, 0); |
|
268 } else if (od.object instanceof QuadCurve2D |
|
269 || od.object instanceof CubicCurve2D) { |
|
270 g2.setStroke(bs); |
|
271 g2.draw((Shape) od.object); |
|
272 } else if (od.object instanceof Shape) { |
|
273 g2.fill((Shape) od.object); |
|
274 } |
|
275 g2.translate(-od.x, -od.y); |
|
276 } |
|
277 } |
|
278 |
|
279 public static void main(String argv[]) { |
|
280 createDemoFrame(new FadeAnim()); |
|
281 } |
|
282 |
|
283 |
|
284 static class TextData extends Object { |
|
285 |
|
286 public String string; |
|
287 public Font font; |
|
288 public int width, height; |
|
289 |
|
290 public TextData(String str, Font font, Component cmp) { |
|
291 string = str; |
|
292 this.font = font; |
|
293 FontMetrics fm = cmp.getFontMetrics(font); |
|
294 width = fm.stringWidth(str); |
|
295 height = fm.getHeight(); |
|
296 } |
|
297 } |
|
298 |
|
299 |
|
300 static class ObjectData extends Object { |
|
301 |
|
302 final int UP = 0; |
|
303 final int DOWN = 1; |
|
304 Object object; |
|
305 BufferedImage bimg; |
|
306 Paint paint; |
|
307 double x, y; |
|
308 float alpha; |
|
309 int alphaDirection; |
|
310 int imgX; |
|
311 |
|
312 public ObjectData(Object object, Paint paint) { |
|
313 this.object = object; |
|
314 this.paint = paint; |
|
315 if (object instanceof BufferedImage) { |
|
316 bimg = (BufferedImage) object; |
|
317 this.object = bimg.getSubimage(0, 0, 80, 80); |
|
318 } |
|
319 getRandomXY(300, 250); |
|
320 alpha = (float) Math.random(); |
|
321 alphaDirection = Math.random() > 0.5 ? UP : DOWN; |
|
322 } |
|
323 |
|
324 private void getRandomXY(int w, int h) { |
|
325 if (object instanceof TextData) { |
|
326 x = Math.random() * (w - ((TextData) object).width); |
|
327 y = Math.random() * h; |
|
328 y = y < ((TextData) object).height ? ((TextData) object).height |
|
329 : y; |
|
330 } else if (object instanceof Image) { |
|
331 x = Math.random() * (w - ((Image) object).getWidth(null)); |
|
332 y = Math.random() * (h - ((Image) object).getHeight(null)); |
|
333 } else if (object instanceof Shape) { |
|
334 Rectangle bounds = ((Shape) object).getBounds(); |
|
335 x = Math.random() * (w - bounds.width); |
|
336 y = Math.random() * (h - bounds.height); |
|
337 } |
|
338 } |
|
339 |
|
340 public void reset(int w, int h) { |
|
341 getRandomXY(w, h); |
|
342 double ww = 20 + Math.random() * ((w == 0 ? 400 : w) / 4); |
|
343 double hh = 20 + Math.random() * ((h == 0 ? 300 : h) / 4); |
|
344 if (object instanceof Ellipse2D) { |
|
345 ((Ellipse2D) object).setFrame(0, 0, ww, hh); |
|
346 } else if (object instanceof Rectangle2D) { |
|
347 ((Rectangle2D) object).setRect(0, 0, ww, ww); |
|
348 } else if (object instanceof RoundRectangle2D) { |
|
349 ((RoundRectangle2D) object).setRoundRect(0, 0, hh, hh, 20, 20); |
|
350 } else if (object instanceof Arc2D) { |
|
351 ((Arc2D) object).setArc(0, 0, hh, hh, 45, 270, Arc2D.PIE); |
|
352 } else if (object instanceof QuadCurve2D) { |
|
353 ((QuadCurve2D) object).setCurve(0, 0, w * .2, h * .4, w * .4, 0); |
|
354 } else if (object instanceof CubicCurve2D) { |
|
355 ((CubicCurve2D) object).setCurve(0, 0, 30, -60, 60, 60, 90, 0); |
|
356 } else if (object instanceof GeneralPath) { |
|
357 GeneralPath p = new GeneralPath(); |
|
358 float size = (float) ww; |
|
359 p.moveTo(-size / 2.0f, -size / 8.0f); |
|
360 p.lineTo(+size / 2.0f, -size / 8.0f); |
|
361 p.lineTo(-size / 4.0f, +size / 2.0f); |
|
362 p.lineTo(+0.0f, -size / 2.0f); |
|
363 p.lineTo(+size / 4.0f, +size / 2.0f); |
|
364 p.closePath(); |
|
365 object = p; |
|
366 } |
|
367 } |
|
368 |
|
369 public void step(int w, int h) { |
|
370 if (object instanceof BufferedImage) { |
|
371 if ((imgX += 80) == 800) { |
|
372 imgX = 0; |
|
373 } |
|
374 object = bimg.getSubimage(imgX, 0, 80, 80); |
|
375 } |
|
376 if (alphaDirection == UP) { |
|
377 if ((alpha += 0.05) > .99) { |
|
378 alphaDirection = DOWN; |
|
379 alpha = 1.0f; |
|
380 } |
|
381 } else if (alphaDirection == DOWN) { |
|
382 if ((alpha -= .05) < 0.01) { |
|
383 alphaDirection = UP; |
|
384 alpha = 0; |
|
385 getRandomXY(w, h); |
|
386 } |
|
387 } |
|
388 } |
|
389 } |
|
390 |
|
391 |
|
392 static class DemoControls extends CustomControls implements ChangeListener { |
|
393 |
|
394 FadeAnim demo; |
|
395 JSlider shapeSlider, stringSlider, imageSlider; |
|
396 Font font = new Font(Font.SERIF, Font.BOLD, 10); |
|
397 |
|
398 @SuppressWarnings("LeakingThisInConstructor") |
|
399 public DemoControls(FadeAnim demo) { |
|
400 super(demo.name); |
|
401 this.demo = demo; |
|
402 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); |
|
403 add(Box.createVerticalStrut(5)); |
|
404 |
|
405 JToolBar toolbar = new JToolBar(SwingConstants.VERTICAL); |
|
406 toolbar.setFloatable(false); |
|
407 shapeSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 20, |
|
408 demo.numShapes); |
|
409 shapeSlider.addChangeListener(this); |
|
410 TitledBorder tb = new TitledBorder(new EtchedBorder()); |
|
411 tb.setTitleFont(font); |
|
412 tb.setTitle(String.valueOf(demo.numShapes) + " Shapes"); |
|
413 shapeSlider.setBorder(tb); |
|
414 shapeSlider.setPreferredSize(new Dimension(80, 45)); |
|
415 shapeSlider.setOpaque(true); |
|
416 toolbar.addSeparator(); |
|
417 toolbar.add(shapeSlider); |
|
418 toolbar.addSeparator(); |
|
419 |
|
420 stringSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 10, |
|
421 demo.numStrings); |
|
422 stringSlider.addChangeListener(this); |
|
423 tb = new TitledBorder(new EtchedBorder()); |
|
424 tb.setTitleFont(font); |
|
425 tb.setTitle(String.valueOf(demo.numStrings) + " Strings"); |
|
426 stringSlider.setBorder(tb); |
|
427 stringSlider.setPreferredSize(new Dimension(80, 45)); |
|
428 stringSlider.setOpaque(true); |
|
429 toolbar.add(stringSlider); |
|
430 toolbar.addSeparator(); |
|
431 |
|
432 imageSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 10, |
|
433 demo.numImages); |
|
434 imageSlider.addChangeListener(this); |
|
435 tb = new TitledBorder(new EtchedBorder()); |
|
436 tb.setTitleFont(font); |
|
437 tb.setTitle(String.valueOf(demo.numImages) + " Images"); |
|
438 imageSlider.setBorder(tb); |
|
439 imageSlider.setPreferredSize(new Dimension(80, 45)); |
|
440 imageSlider.setOpaque(true); |
|
441 toolbar.add(imageSlider); |
|
442 toolbar.addSeparator(); |
|
443 |
|
444 add(toolbar); |
|
445 } |
|
446 |
|
447 @Override |
|
448 public void stateChanged(ChangeEvent e) { |
|
449 JSlider slider = (JSlider) e.getSource(); |
|
450 int value = slider.getValue(); |
|
451 TitledBorder tb = (TitledBorder) slider.getBorder(); |
|
452 if (slider.equals(shapeSlider)) { |
|
453 tb.setTitle(String.valueOf(value) + " Shapes"); |
|
454 demo.setShapes(value); |
|
455 } else if (slider.equals(stringSlider)) { |
|
456 tb.setTitle(String.valueOf(value) + " Strings"); |
|
457 demo.setStrings(value); |
|
458 } else if (slider.equals(imageSlider)) { |
|
459 tb.setTitle(String.valueOf(value) + " Images"); |
|
460 demo.setImages(value); |
|
461 } |
|
462 slider.repaint(); |
|
463 if (!demo.animating.running()) { |
|
464 demo.repaint(); |
|
465 } |
|
466 } |
|
467 |
|
468 @Override |
|
469 public Dimension getPreferredSize() { |
|
470 return new Dimension(80, 0); |
|
471 } |
|
472 |
|
473 @Override |
|
474 public void run() { |
|
475 try { |
|
476 Thread.sleep(999); |
|
477 } catch (InterruptedException e) { |
|
478 return; |
|
479 } |
|
480 shapeSlider.setValue((int) (Math.random() * 5)); |
|
481 stringSlider.setValue(10); |
|
482 thread = null; |
|
483 } |
|
484 } // End DemoControls |
|
485 } // End FadeAnim |
|
486 |