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 repaint.
  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 Polys02
  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 Polys02 extends TestCase {
  43     static boolean TESTXOR = false;
  44     static boolean RUNLONG = false;
  45     static final Random rand = new Random( 0x20406 );
  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   ActivePolygon[] polys = new ActivePolygon[kPolys];
 105         Rectangle rect = null;
 106         TimerTask renderer;
 107 
 108         public AnimatedWindow( Rectangle rect ) throws Exception {
 109             super( "AnimatingFrame" );
 110             this.rect = rect;
 111             setBounds( rect );
 112 
 113             int peX = -SLOP;
 114             int peY = -SLOP;
 115             int peW = rect.width+SLOP;
 116             int peH = rect.height+SLOP;
 117             Rectangle polyedges = new Rectangle(  peX, peY, peW, peH);
 118             for (int i = 0; i<polys.length; i++ ) {
 119                 if (TESTXOR && i % 2 == 0) {
 120                     polys[i] = new XorPolygon( polyedges );
 121                 }
 122                 else {
 123                     polys[i] = new NormalPolygon( polyedges );
 124                 }
 125             }
 126 
 127             setVisible(true);
 128 
 129             // Simple animation into a cached graphics object
 130             renderer = new TimerTask() {
 131                 public void run() {
 132                     AnimatedWindow.this.animateOnce();
 133                     AnimatedWindow.this.repaint();
 134                 }
 135             };
 136             ticktock.schedule(renderer, 0L, 50L);
 137         }
 138 
 139         public void animateOnce() {
 140             for (ActivePolygon item : polys) {
 141                 item.move();
 142             }
 143         }
 144 
 145         public void paint( Graphics gg ) {
 146             super.paint(gg );
 147             gg.setColor(Color.cyan);
 148             gg.fillRect(0, 0, rect.width, rect.height);
 149             for (ActivePolygon item : polys) {
 150                 item.render(gg);
 151             }
 152 
 153         }
 154     }
 155 
 156      volatile boolean done = false;
 157 
 158     public void testPoly() throws Exception {
 159         final AnimatedWindow testWindow = new AnimatedWindow(rect);
 160 
 161         TimerTask stopper = new TimerTask() {
 162             public void run() {
 163                 done = true;
 164             }
 165         };
 166 
 167         if (!RUNLONG) {
 168             ticktock.schedule(stopper, 1250L);
 169         }
 170         else {
 171             ticktock.schedule(stopper, 30000L);
 172         }
 173 
 174         while( done == false) {
 175             Thread.sleep(250);
 176         }
 177 
 178         testWindow.renderer.cancel();
 179         ticktock.cancel();
 180 
 181         SwingUtilities.invokeLater(new Runnable() {
 182             public void run() {
 183                 testWindow.dispose();
 184             }
 185         });
 186     }
 187 
 188     public static Test suite() {
 189         return new TestSuite( Polys02.class);
 190     }
 191 
 192     public static void main( String[] args ) {
 193         for (String arg : args) {
 194             if (arg.toLowerCase().equals("-testxor")) {
 195                 TESTXOR=true;
 196             }
 197             if (arg.toLowerCase().equals("-runlong")) {
 198                 RUNLONG=true;
 199             }
 200         }
 201         TestResult tr = junit.textui.TestRunner.run(suite());
 202         if ((tr.errorCount() != 0) || (tr.failureCount() != 0)) {
 203             throw new RuntimeException("### FAILED: unexpected JUnit errors or failures.");
 204         }
 205     }
 206 }
 207 
 208 
 209