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.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 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 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 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 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 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 176 public AnimVal(boolean isSelected) { 177 this.isSelected = isSelected; 178 } 179 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 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 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 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 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 278 public Dimension getPreferredSize() { 279 return new Dimension(200, 40); 280 } 281 282 @Override 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