1 /*
2  *
3  * Copyright (c) 2007, 2018, 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.Clipping;
33 
34 
35 import java.awt.*;
36 import java.awt.event.*;
37 import java.awt.geom.*;
38 import java.awt.image.BufferedImage;
39 import javax.swing.*;
40 import java2d.AnimatingControlsSurface;
41 import java2d.CustomControls;
42 import static java.lang.Math.random;
43 import static java.awt.Color.*;
44 
45 
46 /**
47  * Animated clipping of an image & composited shapes.
48  */
49 @SuppressWarnings("serial")
50 public class ClipAnim extends AnimatingControlsSurface {
51 
52     private static Image dimg, cimg;
53     static TexturePaint texturePaint;
54 
55     static {
56         BufferedImage bi = new BufferedImage(5, 5, BufferedImage.TYPE_INT_RGB);
57         Graphics2D big = bi.createGraphics();
58         big.setBackground(YELLOW);
59         big.clearRect(0, 0, 5, 5);
60         big.setColor(RED);
61         big.fillRect(0, 0, 3, 3);
62         texturePaint = new TexturePaint(bi, new Rectangle(0, 0, 5, 5));
63     }
64     private AnimVal[] animval = new AnimVal[3];
65     protected boolean doObjects = true;
66     private Font originalFont = new Font(Font.SERIF, Font.PLAIN, 12);
67     private Font font;
68     private GradientPaint gradient;
69     private int strX, strY;
70     private int dukeX, dukeY, dukeWidth, dukeHeight;
71 
ClipAnim()72     public ClipAnim() {
73         cimg = getImage("clouds.jpg");
74         dimg = getImage("duke.png");
75         setBackground(WHITE);
76         animval[0] = new AnimVal(true);
77         animval[1] = new AnimVal(false);
78         animval[2] = new AnimVal(false);
79         setControls(new Component[] { new DemoControls(this) });
80     }
81 
82     @Override
reset(int w, int h)83     public void reset(int w, int h) {
84         for (AnimVal a : animval) {
85             a.reset(w, h);
86         }
87         gradient = new GradientPaint(0, h / 2, RED, w * .4f, h * .9f, YELLOW);
88         double scale = 0.4;
89         dukeHeight = (int) (scale * h);
90         dukeWidth = (int) (dimg.getWidth(this) * scale * h / dimg.getHeight(this));
91         dukeX = (int) (w * .25 - dukeWidth / 2);
92         dukeY = (int) (h * .25 - dukeHeight / 2);
93         FontMetrics fm = getFontMetrics(originalFont);
94         double sw = fm.stringWidth("CLIPPING");
95         double sh = fm.getAscent() + fm.getDescent();
96         double sx = (w / 2 - 30) / sw;
97         double sy = (h / 2 - 30) / sh;
98         AffineTransform Tx = AffineTransform.getScaleInstance(sx, sy);
99         font = originalFont.deriveFont(Tx);
100         fm = getFontMetrics(font);
101         strX = (int) (w * .75 - fm.stringWidth("CLIPPING") / 2);
102         strY = (int) (h * .72 + fm.getAscent() / 2);
103     }
104 
105     @Override
step(int w, int h)106     public void step(int w, int h) {
107         for (AnimVal a : animval) {
108             if (a.isSelected) {
109                 a.step(w, h);
110             }
111         }
112     }
113 
114     @Override
render(int w, int h, Graphics2D g2)115     public void render(int w, int h, Graphics2D g2) {
116 
117         GeneralPath p1 = new GeneralPath();
118         GeneralPath p2 = new GeneralPath();
119 
120         for (AnimVal a : animval) {
121             if (a.isSelected) {
122                 double x = a.x;
123                 double y = a.y;
124                 double ew = a.ew;
125                 double eh = a.eh;
126                 p1.append(new Ellipse2D.Double(x, y, ew, eh), false);
127                 p2.append(new Rectangle2D.Double(x + 5, y + 5, ew - 10, eh - 10),
128                         false);
129             }
130         }
131         if (animval[0].isSelected || animval[1].isSelected
132                 || animval[2].isSelected) {
133             g2.setClip(p1);
134             g2.clip(p2);
135         }
136 
137         if (doObjects) {
138             int w2 = w / 2;
139             int h2 = h / 2;
140             g2.drawImage(cimg, 0, 0, w2, h2, null);
141             g2.drawImage(dimg, dukeX, dukeY, dukeWidth, dukeHeight, null);
142 
143             g2.setPaint(texturePaint);
144             g2.fillRect(w2, 0, w2, h2);
145 
146             g2.setPaint(gradient);
147             g2.fillRect(0, h2, w2, h2);
148 
149             g2.setColor(LIGHT_GRAY);
150             g2.fillRect(w2, h2, w2, h2);
151             g2.setColor(RED);
152             g2.drawOval(w2, h2, w2 - 1, h2 - 1);
153             g2.setFont(font);
154             g2.drawString("CLIPPING", strX, strY);
155         } else {
156             g2.setColor(LIGHT_GRAY);
157             g2.fillRect(0, 0, w, h);
158         }
159     }
160 
main(String[] argv)161     public static void main(String[] argv) {
162         createDemoFrame(new ClipAnim());
163     }
164 
165 
166     public class AnimVal {
167 
168         double ix = 5.0;
169         double iy = 3.0;
170         double iw = 5.0;
171         double ih = 3.0;
172         double x, y;
173         double ew, eh;   // ellipse width & height
174         boolean isSelected;
175 
AnimVal(boolean isSelected)176         public AnimVal(boolean isSelected) {
177             this.isSelected = isSelected;
178         }
179 
step(int w, int h)180         public void step(int w, int h) {
181             x += ix;
182             y += iy;
183             ew += iw;
184             eh += ih;
185 
186             if (ew > w / 2) {
187                 ew = w / 2;
188                 iw = random() * -w / 16 - 1;
189             }
190             if (ew < w / 8) {
191                 ew = w / 8;
192                 iw = random() * w / 16 + 1;
193             }
194             if (eh > h / 2) {
195                 eh = h / 2;
196                 ih = random() * -h / 16 - 1;
197             }
198             if (eh < h / 8) {
199                 eh = h / 8;
200                 ih = random() * h / 16 + 1;
201             }
202 
203             if ((x + ew) > w) {
204                 x = (w - ew) - 1;
205                 ix = random() * -w / 32 - 1;
206             }
207             if ((y + eh) > h) {
208                 y = (h - eh) - 2;
209                 iy = random() * -h / 32 - 1;
210             }
211             if (x < 0) {
212                 x = 2;
213                 ix = random() * w / 32 + 1;
214             }
215             if (y < 0) {
216                 y = 2;
217                 iy = random() * h / 32 + 1;
218             }
219         }
220 
reset(int w, int h)221         public void reset(int w, int h) {
222             x = random() * w;
223             y = random() * h;
224             ew = (random() * w) / 2;
225             eh = (random() * h) / 2;
226         }
227     }
228 
229 
230     static final class DemoControls extends CustomControls implements
231             ActionListener {
232 
233         ClipAnim demo;
234         JToolBar toolbar;
235 
DemoControls(ClipAnim demo)236         public DemoControls(ClipAnim demo) {
237             super(demo.name);
238             this.demo = demo;
239             add(toolbar = new JToolBar());
240             toolbar.setFloatable(false);
241             addTool("Objects", true);
242             addTool("Clip1", true);
243             addTool("Clip2", false);
244             addTool("Clip3", false);
245         }
246 
addTool(String str, boolean state)247         public void addTool(String str, boolean state) {
248             JToggleButton b =
249                     (JToggleButton) toolbar.add(new JToggleButton(str));
250             b.setFocusPainted(false);
251             b.setSelected(state);
252             b.addActionListener(this);
253             int width = b.getPreferredSize().width;
254             Dimension prefSize = new Dimension(width, 21);
255             b.setPreferredSize(prefSize);
256             b.setMaximumSize(prefSize);
257             b.setMinimumSize(prefSize);
258         }
259 
260         @Override
actionPerformed(ActionEvent e)261         public void actionPerformed(ActionEvent e) {
262             JToggleButton b = (JToggleButton) e.getSource();
263             if (b.getText().equals("Objects")) {
264                 demo.doObjects = b.isSelected();
265             } else if (b.getText().equals("Clip1")) {
266                 demo.animval[0].isSelected = b.isSelected();
267             } else if (b.getText().equals("Clip2")) {
268                 demo.animval[1].isSelected = b.isSelected();
269             } else if (b.getText().equals("Clip3")) {
270                 demo.animval[2].isSelected = b.isSelected();
271             }
272             if (!demo.animating.running()) {
273                 demo.repaint();
274             }
275         }
276 
277         @Override
getPreferredSize()278         public Dimension getPreferredSize() {
279             return new Dimension(200, 40);
280         }
281 
282         @Override
run()283         public void run() {
284             try {
285                 Thread.sleep(5000);
286             } catch (InterruptedException e) {
287                 return;
288             }
289             ((AbstractButton) toolbar.getComponentAtIndex(2)).doClick();
290             try {
291                 Thread.sleep(5000);
292             } catch (InterruptedException e) {
293                 return;
294             }
295             if (getSize().width > 400) {
296                 ((AbstractButton) toolbar.getComponentAtIndex(3)).doClick();
297             }
298             thread = null;
299         }
300     } // End DemoControls
301 } // End ClipAnim
302 
303