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 <rdar://problem/3663334> SJSC: 1.4.2DP1: Using a GradientPaint (x, y, color1, x, y, color2, true) hangs AWT thread 27 * @summary com.apple.junit.java.graphics.GradientPaint 28 * @library ../../regtesthelpers 29 * @build VisibilityValidator 30 * @run main R3663334GradientTests 31 */ 32 33 import test.java.awt.regtesthelpers.VisibilityValidator; 34 import junit.framework.*; 35 import javax.swing.*; 36 import java.awt.*; 37 38 39 public class R3663334GradientTests extends TestCase { 40 41 private static final boolean DEBUG = false; 42 43 // Use primary colors to simplify the check that we get back a reasonable gradient 44 private static final Color kGradientPrimary1 = Color.blue; 45 private static final Color kGradientPrimary2 = Color.green; 46 private static final int kColorThreshhold = 32; 47 48 // A color used to check that things draw at all. Since we use green and blue elsewhere, we choose red here 49 private static final Color kBackgroundColor = Color.red; 50 51 private Robot robot; 52 private DisplayFrame m = null; 53 54 // State machine for testXXX() & DisplayFrame 55 private volatile int state = 0; 56 static final int BEFORE_TEST = 0; 57 static final int DOING_TEST = 1; 58 static final int AFTER_TEST = 2; 59 60 class DisplayFrame extends JFrame { 61 int width; 62 int height; 63 64 public DisplayFrame( Dimension gradientSize ) { 65 super("DisplayFrame"); 66 this.width = (int) gradientSize.getWidth(); 67 this.height = (int) gradientSize.getHeight(); 68 setBounds (20, 20, 400, 400); 69 } 70 71 public void makeVisible() throws Exception { 72 } 73 74 public void drawBackdrop (Graphics g) { 75 Dimension size = getSize(); 76 g.setColor(kBackgroundColor); 77 g.fillRect(0, 0, size.width, size.height); 78 } 79 80 public void drawGradient (Graphics g) { 81 // fill with white 82 Dimension size = getSize(); 83 g.setColor(Color.white); // anything but kBackgroundColor 84 g.fillRect(0, 0, size.width, size.height); 85 86 // note that a zero-sized gradient paint may be transparent 87 Graphics2D g2d = (Graphics2D) g; 88 if (DEBUG) System.err.println("Constructing gradient paint"); 89 GradientPaint gp = new GradientPaint (20, 20, kGradientPrimary1, 20+width, 20+height, kGradientPrimary2, true); 90 if (DEBUG) System.err.println("Setting gradient paint"); 91 g2d.setPaint(gp); 92 if (DEBUG) System.err.println("Using gradient paint"); 93 g.fillRect (0,0,getWidth(),getHeight()); 94 } 95 96 public void paint (Graphics g) { 97 switch (state) { 98 case BEFORE_TEST: 99 drawBackdrop(g); 100 break; 101 102 case DOING_TEST: 103 drawGradient(g); 104 break; 105 106 case AFTER_TEST: 107 drawBackdrop(g); 108 break; 109 } 110 } 111 } 112 113 protected void setUp() throws Exception { 114 robot = new Robot(); 115 } 116 117 protected void tearDown() throws Exception { 118 m.dispose(); 119 } 120 121 public void testGradientPaintDrawsReasonableColors() throws Exception { 122 Dimension gradientSize = new Dimension(100,10); 123 m = new DisplayFrame(gradientSize); 124 VisibilityValidator.setVisibleAndConfirm(m); 125 126 // Now do some heavily bullet-proofed checks that we are visible 127 128 // 1 make sure the frame is up - loop until the frame is and we see the red backdrop 129 state = BEFORE_TEST; 130 assertTrue("Problems waiting for background to draw.", waitOnCenterColor(m, EXPECT_BACKGROUND) ); 131 132 // 2 loop until the frame is changes from red to something else 133 state = DOING_TEST; 134 m.repaint(); 135 assertTrue("Problems waiting for gradient to draw.", waitOnCenterColor(m, !EXPECT_BACKGROUND)); 136 // checkForGoodColors(); 137 138 // 3 loop until the frame changes back to the red backdrop 139 state = AFTER_TEST; 140 m.repaint(); 141 assertTrue("Problems waiting for old background to draw.", waitOnCenterColor(m, EXPECT_BACKGROUND) ); 142 } 143 144 public void testZeroSizedGradientPaintDoesntHang() throws Exception { 145 Dimension gradientSize = new Dimension(0,0); 146 m = new DisplayFrame(gradientSize); 147 VisibilityValidator.setVisibleAndConfirm(m); 148 149 // Now do some heavily bullet-proofed checks that we are visible 150 151 // 1) make sure the frame is up - loop until the frame is and we see the red backdrop 152 state = BEFORE_TEST; 153 assertTrue("Problems waiting for background to draw.", waitOnCenterColor(m, EXPECT_BACKGROUND) ); 154 155 // 2) loop until the frame is changes from red to something else 156 state = DOING_TEST; 157 m.repaint(); 158 assertTrue("Problems waiting for gradient to draw.", waitOnCenterColor(m, !EXPECT_BACKGROUND)); 159 160 // 3) loop until the frame changes back to the red backdrop 161 state = AFTER_TEST; 162 m.repaint(); 163 assertTrue("Problems waiting for old background to draw.", waitOnCenterColor(m, EXPECT_BACKGROUND)); 164 } 165 166 167 // Test for valid colors. Poke around the center some. Note that the colors used in the gradient for this testcase were specially 168 // chosen to make these checks easier; this code will not work for any random Gradient fill. 169 170 void checkForGoodColors() throws Exception { 171 Rectangle r = m.getBounds(); 172 173 assertTrue( "Needs a reasonable sized rectangle", r.getWidth() > 10); 174 assertTrue( "Needs a reasonable sized rectangle", r.getHeight() > 10); 175 176 int x = (int) r.getX() + (int) r.getWidth() / 2; 177 int y = (int) r.getY() + (int) r.getHeight() / 2; 178 179 for (int i = -4; i <=4; i++) { 180 for (int j = -4; j <=4; j++) { 181 Color c = null; 182 c = robot.getPixelColor(x+i, y+j); 183 // Is c reasonable based on gradient parameters? 184 // We used primary colors for the two ends of the gradient, so the sum of the colors should be close to 255 185 assertTrue( "Unexpected color in gradient fill", c.getRed() + c.getGreen() + c.getBlue() > (255 - kColorThreshhold) ); 186 assertTrue( "Unexpected color in gradient fill", c.getRed() + c.getGreen() + c.getBlue() <= 255 ); 187 188 // We avoided red altogether, so we shouldnt have much red 189 assertTrue( "Unexpected color in gradient fill", c.getRed() < kColorThreshhold ); 190 } 191 } 192 } 193 194 // A loop that actively tries to repaint the component until the color of the center pixel does something interesting. 195 // Note the the result needs to be checked afterwards, as the loop times out after a bit (kPaintingTimeoutMillis) 196 // 197 // a) expectBackground == true ( waits for us to match the background) 198 // b) expectBackground == false ( waits for us to NOT match the background) 199 200 static final int kPaintingTimeoutMillis = 10000; 201 static final boolean EXPECT_BACKGROUND = true; 202 203 public boolean waitOnCenterColor(Component comp, boolean expectBackground) throws Exception { 204 boolean gotExpectedColor = false; 205 Rectangle r = comp.getBounds(); 206 int x = (int) r.getX() + (int) r.getWidth() / 2; 207 int y = (int) r.getY() + (int) r.getHeight() / 2; 208 209 Color c = null; 210 long endtime = System.currentTimeMillis() + kPaintingTimeoutMillis; 211 while (System.currentTimeMillis() < endtime) { 212 c = robot.getPixelColor(x, y); 213 if (DEBUG) System.err.println(c); 214 // Loop until we see what we expect to see, or we timeout 215 if (VisibilityValidator.colorMatch(kBackgroundColor, c) == expectBackground) { 216 gotExpectedColor = true; 217 break; // we see what we expect, continue 218 } 219 220 // loop needs to actively repaint, as sometimes paints are not synchronous 221 m.repaint(); 222 Thread.sleep(250); // a vaguely reasonable time to wait for a repaint to finish 223 } 224 225 return (gotExpectedColor); 226 } 227 228 // Boilerplate below 229 230 public static Test suite() { 231 return new TestSuite(R3663334GradientTests.class); 232 } 233 234 public static void main (String[] args) throws RuntimeException { 235 TestResult tr = junit.textui.TestRunner.run(suite()); 236 if ((tr.errorCount() != 0) || (tr.failureCount() != 0)) { 237 throw new RuntimeException("### FAILED: unexpected JUnit errors or failures."); 238 } 239 } 240 241 242 }