1 /* 2 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @summary Paints a couple of animated polygons using a cached graphics object. 27 * @summary <rdar://problem/4939642> [JavaJDK15] g.fillPolygon crashes JVM under XORMode 28 * @summary com.apple.junit.java.graphics.images 29 * @library ../../regtesthelpers 30 * @build MovingPoints 31 * @run junit Polys01 32 */ 33 34 import test.java.awt.regtesthelpers.MovingPoints; 35 import junit.framework.*; 36 import javax.swing.*; 37 import java.awt.*; 38 import java.util.*; 39 import java.util.Timer; 40 41 42 public class Polys01 extends TestCase { 43 static boolean TESTXOR = false; 44 static boolean RUNLONG = false; 45 static final Random rand = new Random( ); 46 Timer ticktock = new Timer(); 47 48 // 49 // Constants controlling the scene 50 // 51 static Rectangle rect = new Rectangle( 40, 40, 350, 400 ); 52 static final int SLOP = 120; 53 static final int kPolys = 5; 54 55 // 56 // An animator class so the scene is vaguely interesting 57 // 58 abstract protected class ActivePolygon extends MovingPoints { 59 protected Color color = null; 60 // Some initial conditions 61 62 public ActivePolygon(Rectangle r) { 63 super(r, Math.max(3, rand.nextInt(5) + rand.nextInt(5) + rand.nextInt(5))); 64 color = new Color(rand.nextInt(0xFF), rand.nextInt(0xFF), rand.nextInt(0xFF)); 65 } 66 67 abstract public void render(Graphics g); 68 } 69 70 // 71 // A polygon that draws via setColor 72 // 73 class NormalPolygon extends ActivePolygon { 74 75 public NormalPolygon(Rectangle r) { 76 super(r); 77 } 78 79 public void render(Graphics g) { 80 g.setColor(color); 81 g.fillPolygon(new Polygon(getXs(), getYs(), getNumVertices())); 82 } 83 } 84 85 // 86 // A polygon that draws via setXORMode 87 // 88 class XorPolygon extends ActivePolygon { 89 90 public XorPolygon(Rectangle r) { 91 super(r); 92 } 93 94 public void render(Graphics g) { 95 g.setXORMode(color); 96 g.fillPolygon(new Polygon(getXs(), getYs(), getNumVertices())); 97 } 98 } 99 100 /* 101 */ 102 103 class AnimatedWindow extends Frame { 104 volatile Graphics cachedGraphics = null; 105 volatile ActivePolygon[] polys = new ActivePolygon[kPolys]; 106 107 Rectangle rect = null; 108 TimerTask renderer; 109 110 public AnimatedWindow( Rectangle rect ) throws Exception { 111 super( "AnimatingFrame" ); 112 this.rect = rect; 113 setBounds( rect ); 114 115 int peX = -SLOP; 116 int peY = -SLOP; 117 int peW = rect.width+SLOP; 118 int peH = rect.height+SLOP; 119 Rectangle polyedges = new Rectangle( peX, peY, peW, peH); 120 for (int i = 0; i<polys.length; i++ ) { 121 if (TESTXOR && i % 2 == 0) { 122 polys[i] = new XorPolygon( polyedges ); 123 } 124 else { 125 polys[i] = new NormalPolygon( polyedges ); 126 } 127 128 } 129 130 setVisible(true); 131 132 // Simple animation into a cached graphics object 133 cachedGraphics = AnimatedWindow.this.getGraphics(); 134 renderer = new TimerTask() { 135 @Override 136 public void run() { 137 AnimatedWindow.this.animateOnce(); 138 } 139 }; 140 ticktock.schedule(renderer, 0L, 50L); 141 } 142 143 public void animateOnce() { 144 cachedGraphics.setColor(Color.cyan); 145 cachedGraphics.fillRect(0, 0, rect.width, rect.height); 146 for (ActivePolygon item : polys) { 147 item.move(); 148 item.render(cachedGraphics); 149 } 150 } 151 152 @Override 153 public void paint( Graphics gg ) { 154 super.paint( gg ); 155 } 156 } 157 158 volatile boolean done = false; 159 160 public void testPoly() throws Exception { 161 final AnimatedWindow testWindow = new AnimatedWindow(rect); 162 163 TimerTask stopper = new TimerTask() { 164 @Override 165 public void run() { 166 done = true; 167 } 168 }; 169 170 if (!RUNLONG) { 171 ticktock.schedule(stopper, 1250L); 172 } 173 else { 174 ticktock.schedule(stopper, 30000L); 175 } 176 177 while(!done) { 178 Thread.sleep(250); 179 } 180 181 testWindow.renderer.cancel(); 182 ticktock.cancel(); 183 184 SwingUtilities.invokeLater(new Runnable() { 185 public void run() { 186 testWindow.dispose(); 187 } 188 }); 189 } 190 191 public static Test suite() { 192 return new TestSuite( Polys01.class); 193 } 194 195 public static void main( String[] args ) { 196 for (String arg : args) { 197 if (arg.toLowerCase().equals("-testxor")) { 198 TESTXOR=true; 199 } 200 if (arg.toLowerCase().equals("-runlong")) { 201 RUNLONG=true; 202 } 203 } 204 TestResult tr = junit.textui.TestRunner.run(suite()); 205 if ((tr.errorCount() != 0) || (tr.failureCount() != 0)) { 206 throw new RuntimeException("### FAILED: unexpected JUnit errors or failures."); 207 } 208 } 209 } 210 211 212