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 33 34 package java2d.demos.Clipping; 35 36 37 import java.awt.*; 38 import java.awt.event.*; 39 import java.awt.geom.*; 40 import java.awt.font.FontRenderContext; 41 import java.awt.font.TextLayout; 42 import javax.swing.*; 43 import java2d.AnimatingControlsSurface; 44 import java2d.CustomControls; 45 import static java.awt.Color.*; 46 47 48 /** 49 * Animated intersection clipping of lines, an image and a textured rectangle. 50 */ 51 @SuppressWarnings("serial") 52 public class Intersection extends AnimatingControlsSurface { 53 54 private static final int HEIGHT_DECREASE = 0; 55 private static final int HEIGHT_INCREASE = 1; 56 private static final int WIDTH_DECREASE = 2; 57 private static final int WIDTH_INCREASE = 3; 58 59 private int xx, yy, ww, hh; 60 private int direction = HEIGHT_DECREASE; 61 private int angdeg; 62 private Shape textshape; 63 private double sw, sh; 64 private GeneralPath ovals; 65 private Rectangle2D rectshape; 66 protected boolean doIntersection = true; 67 protected boolean doOvals = true; 68 protected boolean doText; 69 protected boolean threeSixty; 70 71 Intersection()72 public Intersection() { 73 setBackground(WHITE); 74 setControls(new Component[] { new DemoControls(this) }); 75 } 76 77 78 @Override reset(int w, int h)79 public void reset(int w, int h) { 80 xx = yy = 0; 81 ww = w-1; hh = h; 82 direction = HEIGHT_DECREASE; 83 angdeg = 0; 84 FontRenderContext frc = new FontRenderContext(null, true, false); 85 Font f = new Font(Font.SERIF, Font.BOLD,32); 86 TextLayout tl = new TextLayout("J2D", f, frc); 87 sw = tl.getBounds().getWidth(); 88 sh = tl.getBounds().getHeight(); 89 int size = Math.min(w, h); 90 double sx = (size-40)/sw; 91 double sy = (size-100)/sh; 92 AffineTransform Tx = AffineTransform.getScaleInstance(sx, sy); 93 textshape = tl.getOutline(Tx); 94 rectshape = textshape.getBounds(); 95 sw = rectshape.getWidth(); 96 sh = rectshape.getHeight(); 97 ovals = new GeneralPath(); 98 ovals.append(new Ellipse2D.Double( 10, 10, 20, 20), false); 99 ovals.append(new Ellipse2D.Double(w-30, 10, 20, 20), false); 100 ovals.append(new Ellipse2D.Double( 10, h-30, 20, 20), false); 101 ovals.append(new Ellipse2D.Double(w-30, h-30, 20, 20), false); 102 } 103 104 105 @Override step(int w, int h)106 public void step(int w, int h) { 107 if (direction == HEIGHT_DECREASE) { 108 yy+=2; hh-=4; 109 if (yy >= h/2) { 110 direction = HEIGHT_INCREASE; 111 } 112 } else if (direction == HEIGHT_INCREASE) { 113 yy-=2; hh+=4; 114 if (yy <= 0) { 115 direction = WIDTH_DECREASE; 116 hh = h-1; yy = 0; 117 } 118 } 119 if (direction == WIDTH_DECREASE) { 120 xx+=2; ww-=4; 121 if (xx >= w/2) { 122 direction = WIDTH_INCREASE; 123 } 124 } else if (direction == WIDTH_INCREASE) { 125 xx-=2; ww+=4; 126 if (xx <= 0) { 127 direction = HEIGHT_DECREASE; 128 ww = w-1; xx = 0; 129 } 130 } 131 if ((angdeg += 5) == 360) { 132 angdeg = 0; 133 threeSixty = true; 134 } 135 } 136 137 138 @Override render(int w, int h, Graphics2D g2)139 public void render(int w, int h, Graphics2D g2) { 140 141 Rectangle rect = new Rectangle(xx, yy, ww, hh); 142 143 AffineTransform Tx = new AffineTransform(); 144 Tx.rotate(Math.toRadians(angdeg),w/2,h/2); 145 Tx.translate(w/2-sw/2, sh+(h-sh)/2); 146 147 GeneralPath path = new GeneralPath(); 148 if (doOvals) { 149 path.append(ovals, false); 150 } 151 if (doText) { 152 path.append(Tx.createTransformedShape(textshape), false); 153 } else { 154 path.append(Tx.createTransformedShape(rectshape), false); 155 } 156 157 if (doIntersection) { 158 g2.clip(rect); 159 g2.clip(path); 160 } 161 162 g2.setColor(GREEN); 163 g2.fill(rect); 164 165 g2.setClip(new Rectangle(0, 0, w, h)); 166 167 g2.setColor(LIGHT_GRAY); 168 g2.draw(rect); 169 g2.setColor(BLACK); 170 g2.draw(path); 171 } 172 173 main(String[] argv)174 public static void main(String[] argv) { 175 createDemoFrame(new Intersection()); 176 } 177 178 179 static final class DemoControls extends CustomControls implements ActionListener { 180 181 Intersection demo; 182 JToolBar toolbar; 183 DemoControls(Intersection demo)184 public DemoControls(Intersection demo) { 185 super(demo.name); 186 this.demo = demo; 187 add(toolbar = new JToolBar()); 188 toolbar.setFloatable(false); 189 addTool("Intersect", true ); 190 addTool("Text", false); 191 addTool("Ovals", true ); 192 } 193 194 addTool(String str, boolean state)195 public void addTool(String str, boolean state) { 196 JToggleButton b = (JToggleButton) toolbar.add(new JToggleButton(str)); 197 b.setFocusPainted(false); 198 b.setSelected(state); 199 b.addActionListener(this); 200 int width = b.getPreferredSize().width; 201 Dimension prefSize = new Dimension(width, 21); 202 b.setPreferredSize(prefSize); 203 b.setMaximumSize( prefSize); 204 b.setMinimumSize( prefSize); 205 } 206 207 208 @Override actionPerformed(ActionEvent e)209 public void actionPerformed(ActionEvent e) { 210 JToggleButton b = (JToggleButton) e.getSource(); 211 if (b.getText().equals("Intersect")) { 212 demo.doIntersection = b.isSelected(); 213 } else if (b.getText().equals("Ovals")) { 214 demo.doOvals = b.isSelected(); 215 } else if (b.getText().equals("Text")) { 216 demo.doText = b.isSelected(); 217 } 218 if (!demo.animating.running()) { 219 demo.repaint(); 220 } 221 } 222 223 @Override getPreferredSize()224 public Dimension getPreferredSize() { 225 return new Dimension(200,40); 226 } 227 228 229 @Override 230 @SuppressWarnings("SleepWhileHoldingLock") run()231 public void run() { 232 Thread me = Thread.currentThread(); 233 while (thread == me) { 234 if (demo.threeSixty) { 235 ((AbstractButton) toolbar.getComponentAtIndex(1)).doClick(); 236 demo.threeSixty = false; 237 } 238 try { 239 Thread.sleep(500); 240 } catch (InterruptedException e) { return; } 241 } 242 thread = null; 243 } 244 } // End DemoControls 245 } // End Intersection 246