1 /* 2 * Copyright (c) 2014, 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 import java.awt.*; 25 import java.awt.event.*; 26 import java.awt.geom.Area; 27 import java.awt.geom.Rectangle2D; 28 import java.awt.image.BufferedImage; 29 import java.security.SecureRandom; 30 31 32 /* 33 * @author Dmitriy Ermashov (dmitriy.ermashov@oracle.com) 34 */ 35 public abstract class Common { 36 37 ExtendedRobot robot; 38 Class<? extends Frame> windowClass; 39 Frame background; 40 BufferedImage foreground; 41 Window window; 42 Container componentsContainer; 43 44 float opacity = 1.0f; 45 static final int STATIC_STEP = 30; 46 static final int STATIC_WIDTH = 25; 47 static final int STATIC_BLOCKS = 30; 48 static final Color BG_COLOR = Color.BLUE; 49 static final Color FG_COLOR = Color.RED; 50 static final int delay = 1000; 51 static final SecureRandom random = new SecureRandom(); 52 static final int dl = 100; 53 static final Class[] WINDOWS_TO_TEST = { Window.class, Frame.class, Dialog.class }; 54 55 public Common(Class windowClass, float opacity) throws Exception{ 56 this.opacity = opacity; 57 robot = new ExtendedRobot(); 58 this.windowClass = windowClass; 59 EventQueue.invokeAndWait(this::initBackgroundFrame); 60 EventQueue.invokeAndWait(this::initGUI); 61 } 62 63 public Common(Class windowClass) throws Exception{ 64 this(windowClass, 1.0f); 65 } 66 67 void drag (int fromX, int fromY, int toX, int toY) throws Exception { 68 robot.mouseMove(fromX, fromY); 69 robot.waitForIdle(delay); 70 robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); 71 robot.waitForIdle(delay); 72 robot.glide(toX, toY); 73 robot.waitForIdle(delay); 74 robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); 75 } 76 77 public void doTest() throws Exception { 78 robot.waitForIdle(delay); 79 }; 80 81 public void dispose() { 82 window.dispose(); 83 background.dispose(); 84 } 85 86 public abstract void applyShape(); 87 88 public void applyDynamicShape() { 89 final Area a = new Area(); 90 Dimension size = window.getSize(); 91 for (int x = 0; x < 3; x++) { 92 for (int y = 0; y < 3; y++) { 93 a.add(new Area(new Rectangle2D.Double( 94 x * size.getWidth() / 17*6, y * size.getHeight() / 17*6, 95 size.getWidth() / 17*5, size.getHeight() / 17*5))); 96 } 97 } 98 window.setShape(a); 99 } 100 101 public void applyStaticShape() { 102 final Area a = new Area(); 103 for (int x = 0; x < STATIC_BLOCKS; x++) { 104 for (int y = 0; y < STATIC_BLOCKS; y++) { 105 a.add(new Area(new Rectangle2D.Float( 106 x*STATIC_STEP, y*STATIC_STEP, 107 STATIC_WIDTH, STATIC_WIDTH))); 108 } 109 } 110 window.setShape(a); 111 } 112 113 public BufferedImage getForegroundWindow() throws Exception { 114 final BufferedImage f[] = new BufferedImage[1]; 115 EventQueue.invokeAndWait( () -> { 116 f[0] = new BufferedImage(window.getWidth(), 117 window.getHeight(), BufferedImage.TYPE_INT_RGB); 118 window.printAll(f[0].createGraphics()); 119 }); 120 robot.waitForIdle(delay); 121 return f[0]; 122 } 123 124 public static void checkTranslucencyMode(GraphicsDevice.WindowTranslucency mode) { 125 if (!GraphicsEnvironment 126 .getLocalGraphicsEnvironment() 127 .getDefaultScreenDevice() 128 .isWindowTranslucencySupported(mode)) 129 throw new RuntimeException(mode+" translucency mode isn't supported"); 130 } 131 132 public void applyAppDragNResizeSupport() { 133 MouseAdapter m = new MouseAdapter() { 134 135 private Point dragOrigin = null; 136 private Dimension origSize = null; 137 private Point origLoc = null; 138 private boolean left = false; 139 private boolean top = false; 140 private boolean bottom = false; 141 private boolean right = false; 142 143 public void mousePressed(MouseEvent e) { 144 dragOrigin = e.getLocationOnScreen(); 145 origSize = window.getSize(); 146 origLoc = window.getLocationOnScreen(); 147 right = (origLoc.x + window.getWidth() - dragOrigin.x) < 5; 148 left = !right && dragOrigin.x - origLoc.x < 5; 149 bottom = (origLoc.y + window.getHeight() - dragOrigin.y) < 5; 150 top = !bottom && dragOrigin.y - origLoc.y < 5; 151 } 152 153 public void mouseReleased(MouseEvent e) { resize(e); } 154 public void mouseDragged(MouseEvent e) { resize(e); } 155 156 void resize(MouseEvent e) { 157 Point dragDelta = e.getLocationOnScreen(); 158 dragDelta.translate(-dragOrigin.x, -dragOrigin.y); 159 Point newLoc = new Point(origLoc); 160 newLoc.translate(dragDelta.x, dragDelta.y); 161 Dimension newSize = new Dimension(origSize); 162 if (left || right) { 163 newSize.width += right ? dragDelta.x : -dragDelta.x; 164 } 165 if (top || bottom) { 166 newSize.height += bottom ? dragDelta.y : -dragDelta.y; 167 } 168 if (right || (top || bottom) && !left) { 169 newLoc.x = origLoc.x; 170 } 171 if (bottom || (left || right) && !top) { 172 newLoc.y = origLoc.y; 173 } 174 window.setBounds(newLoc.x, newLoc.y, newSize.width, newSize.height); 175 } 176 }; 177 for (Component comp : window.getComponents()) { 178 comp.addMouseListener(m); 179 comp.addMouseMotionListener(m); 180 } 181 182 window.addMouseListener(m); 183 window.addMouseMotionListener(m); 184 } 185 186 public void checkTranslucentShape() throws Exception { 187 foreground = getForegroundWindow(); 188 Point[] points = new Point[4]; 189 190 Dimension size = window.getSize(); 191 Point location = window.getLocationOnScreen(); 192 193 points[0] = new Point(20, 20); 194 points[1] = new Point(20, size.height-20); 195 points[2] = new Point(size.width-20, 20); 196 points[3] = new Point(size.width-20, size.height-20); 197 198 for (Point p : points){ 199 p.translate(location.x, location.y); 200 Color actual = robot.getPixelColor(p.x, p.y); 201 if (actual.equals(BG_COLOR)|| actual.equals(FG_COLOR)) 202 throw new RuntimeException("Error in point "+p+": "+actual+" equals to foreground or background color"); 203 else 204 System.out.println("OK with foreground point "+p); 205 } 206 } 207 208 public void checkStaticShape() throws Exception { 209 Point[] points = new Point[4]; 210 211 Dimension size = window.getSize(); 212 int xFactor = (int) Math.floor(size.getWidth()/STATIC_STEP)-1; 213 int yFactor = (int) Math.floor(size.getHeight()/STATIC_STEP)-1; 214 215 // background 216 points[0] = new Point((STATIC_STEP+STATIC_WIDTH)/2, (STATIC_STEP+STATIC_WIDTH)/2); 217 points[1] = new Point(STATIC_STEP*xFactor+(STATIC_STEP+STATIC_WIDTH)/2, STATIC_STEP*yFactor+(STATIC_STEP+STATIC_WIDTH)/2); 218 points[2] = new Point((STATIC_STEP+STATIC_WIDTH)/2, STATIC_STEP*yFactor+(STATIC_STEP+STATIC_WIDTH)/2); 219 points[3] = new Point(STATIC_STEP*xFactor+(STATIC_STEP+STATIC_WIDTH)/2, (STATIC_STEP+STATIC_WIDTH)/2); 220 checkShape(points, true); 221 222 // foreground 223 if (opacity < 1.0f){ 224 checkTranslucentShape(); 225 } else { 226 points[0] = new Point((STATIC_WIDTH) / 2, (STATIC_WIDTH) / 2); 227 points[1] = new Point(STATIC_STEP * xFactor + (STATIC_WIDTH) / 2, STATIC_STEP * yFactor + (STATIC_WIDTH) / 2); 228 points[2] = new Point((STATIC_WIDTH) / 2, STATIC_STEP * yFactor + (STATIC_WIDTH) / 2); 229 points[3] = new Point(STATIC_STEP * xFactor + (STATIC_WIDTH) / 2, (STATIC_WIDTH) / 2); 230 checkShape(points, false); 231 } 232 } 233 234 public void checkDynamicShape() throws Exception { 235 Point[] points = new Point[4]; 236 237 Dimension size = window.getSize(); 238 239 int blockSizeX = (int) (size.getWidth() / 17); 240 int blockSizeY = (int) (size.getHeight() / 17); 241 242 // background 243 points[0] = new Point((int) (blockSizeX * 5.5), (int) (blockSizeY * 5.5)); 244 points[1] = new Point((int) (size.getWidth() - blockSizeX * 5.5), (int) (size.getHeight() - blockSizeY * 5.5)); 245 points[2] = new Point((int) (blockSizeX * 5.5), (int) (size.getHeight() - blockSizeY * 5.5)); 246 points[3] = new Point((int) (size.getWidth() - blockSizeX * 5.5), (int) (blockSizeY * 5.5)); 247 checkShape(points, true); 248 249 // foreground 250 if (opacity < 1.0f){ 251 checkTranslucentShape(); 252 } else { 253 points[0] = new Point(3 * blockSizeX, 3 * blockSizeY); 254 points[1] = new Point(14 * blockSizeX, 14 * blockSizeY); 255 points[2] = new Point(3 * blockSizeX, 14 * blockSizeY); 256 points[3] = new Point(14 * blockSizeX, 3 * blockSizeY); 257 checkShape(points, false); 258 } 259 } 260 261 public void checkShape(Point[] points, boolean areBackgroundPoints) throws Exception { 262 263 Point location = window.getLocationOnScreen(); 264 265 for (Point p : points) { 266 p.translate(location.x, location.y); 267 if (areBackgroundPoints) { 268 if (!robot.getPixelColor(p.x, p.y).equals(BG_COLOR)) 269 throw new RuntimeException("Background point " + p + " color " + robot.getPixelColor(p.x, p.y) + 270 " does not equal to background color " + BG_COLOR); 271 else 272 System.out.println("OK with background point " + p); 273 } else { 274 if (robot.getPixelColor(p.x, p.y).equals(BG_COLOR)) 275 throw new RuntimeException("Foreground point " + p + 276 " equals to background color " + BG_COLOR); 277 else 278 System.out.println("OK with foreground point " + p); 279 } 280 } 281 } 282 283 public void initBackgroundFrame() { 284 background = new Frame(); 285 background.setUndecorated(true); 286 background.setBackground(BG_COLOR); 287 background.setSize(500, 500); 288 background.setLocation(dl, dl); 289 background.setVisible(true); 290 } 291 292 public void initGUI() { 293 if (windowClass.equals(Frame.class)) { 294 window = new Frame(); 295 ((Frame) window).setUndecorated(true); 296 } else if (windowClass.equals(Dialog.class)) { 297 window = new Dialog(background); 298 ((Dialog) window).setUndecorated(true); 299 } else { 300 window = new Window(background); 301 } 302 303 window.setBackground(FG_COLOR); 304 componentsContainer = new Panel(); 305 window.add(componentsContainer, BorderLayout.CENTER); 306 window.setLocation(2 * dl, 2 * dl); 307 window.setSize(255, 255); 308 if (opacity < 1.0f) 309 window.setOpacity(opacity); 310 window.addComponentListener(new ComponentAdapter() { 311 public void componentResized(ComponentEvent e) { 312 applyShape(); 313 } 314 }); 315 applyShape(); 316 window.setVisible(true); 317 applyAppDragNResizeSupport(); 318 window.toFront(); 319 } 320 }