--- /dev/null 2014-04-25 17:45:41.836278938 +0400 +++ new/test/java/awt/Window/ShapedAndTranslucentWindows/Common.java 2014-04-29 14:21:29.355068000 +0400 @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.*; +import java.awt.event.*; +import java.awt.geom.Area; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.security.SecureRandom; + + +/* + * @author Dmitriy Ermashov (dmitriy.ermashov@oracle.com) + */ +public abstract class Common { + + ExtendedRobot robot; + Class windowClass; + Frame background; + BufferedImage foreground; + Window window; + Container componentsContainer; + + float opacity = 1.0f; + static final int STATIC_STEP = 30; + static final int STATIC_WIDTH = 25; + static final int STATIC_BLOCKS = 30; + static final Color BG_COLOR = Color.BLUE; + static final Color FG_COLOR = Color.RED; + static final int delay = 1000; + static final SecureRandom random = new SecureRandom(); + static final int dl = 100; + static final Class[] WINDOWS_TO_TEST = { Window.class, Frame.class, Dialog.class }; + + public Common(Class windowClass, float opacity) throws Exception{ + this.opacity = opacity; + robot = new ExtendedRobot(); + this.windowClass = windowClass; + EventQueue.invokeAndWait(this::initBackgroundFrame); + EventQueue.invokeAndWait(this::initGUI); + } + + public Common(Class windowClass) throws Exception{ + this(windowClass, 1.0f); + } + + public void doTest() throws Exception { + robot.waitForIdle(delay); + }; + + public void dispose() { + window.dispose(); + background.dispose(); + } + + public abstract void applyShape(); + + public void applyDynamicShape() { + final Area a = new Area(); + Dimension size = window.getSize(); + for (int x = 0; x < 3; x++) { + for (int y = 0; y < 3; y++) { + a.add(new Area(new Rectangle2D.Double( + x * size.getWidth() / 17*6, y * size.getHeight() / 17*6, + size.getWidth() / 17*5, size.getHeight() / 17*5))); + } + } + window.setShape(a); + } + + public void applyStaticShape() { + final Area a = new Area(); + for (int x = 0; x < STATIC_BLOCKS; x++) { + for (int y = 0; y < STATIC_BLOCKS; y++) { + a.add(new Area(new Rectangle2D.Float( + x*STATIC_STEP, y*STATIC_STEP, + STATIC_WIDTH, STATIC_WIDTH))); + } + } + window.setShape(a); + } + + public BufferedImage getForegroundWindow() throws Exception { + final BufferedImage f[] = new BufferedImage[1]; + EventQueue.invokeAndWait( () -> { + f[0] = new BufferedImage(window.getWidth(), + window.getHeight(), BufferedImage.TYPE_INT_RGB); + window.printAll(f[0].createGraphics()); + }); + robot.waitForIdle(delay); + return f[0]; + } + + public static boolean checkTranslucencyMode(GraphicsDevice.WindowTranslucency mode) { + + if (!GraphicsEnvironment + .getLocalGraphicsEnvironment() + .getDefaultScreenDevice() + .isWindowTranslucencySupported(mode)){ + System.out.println(mode+" translucency mode isn't supported"); + return false; + } else { + return true; + } + + } + + public void applyAppDragNResizeSupport() { + MouseAdapter m = new MouseAdapter() { + + private Point dragOrigin = null; + private Dimension origSize = null; + private Point origLoc = null; + private boolean left = false; + private boolean top = false; + private boolean bottom = false; + private boolean right = false; + + public void mousePressed(MouseEvent e) { + dragOrigin = e.getLocationOnScreen(); + origSize = window.getSize(); + origLoc = window.getLocationOnScreen(); + right = (origLoc.x + window.getWidth() - dragOrigin.x) < 5; + left = !right && dragOrigin.x - origLoc.x < 5; + bottom = (origLoc.y + window.getHeight() - dragOrigin.y) < 5; + top = !bottom && dragOrigin.y - origLoc.y < 5; + } + + public void mouseReleased(MouseEvent e) { resize(e); } + public void mouseDragged(MouseEvent e) { resize(e); } + + void resize(MouseEvent e) { + Point dragDelta = e.getLocationOnScreen(); + dragDelta.translate(-dragOrigin.x, -dragOrigin.y); + Point newLoc = new Point(origLoc); + newLoc.translate(dragDelta.x, dragDelta.y); + Dimension newSize = new Dimension(origSize); + if (left || right) { + newSize.width += right ? dragDelta.x : -dragDelta.x; + } + if (top || bottom) { + newSize.height += bottom ? dragDelta.y : -dragDelta.y; + } + if (right || (top || bottom) && !left) { + newLoc.x = origLoc.x; + } + if (bottom || (left || right) && !top) { + newLoc.y = origLoc.y; + } + window.setBounds(newLoc.x, newLoc.y, newSize.width, newSize.height); + } + }; + for (Component comp : window.getComponents()) { + comp.addMouseListener(m); + comp.addMouseMotionListener(m); + } + + window.addMouseListener(m); + window.addMouseMotionListener(m); + } + + public void checkTranslucentShape() throws Exception { + foreground = getForegroundWindow(); + Point[] points = new Point[4]; + + Dimension size = window.getSize(); + Point location = window.getLocationOnScreen(); + + points[0] = new Point(20, 20); + points[1] = new Point(20, size.height-20); + points[2] = new Point(size.width-20, 20); + points[3] = new Point(size.width-20, size.height-20); + + for (Point p : points){ + p.translate(location.x, location.y); + Color actual = robot.getPixelColor(p.x, p.y); + if (actual.equals(BG_COLOR)|| actual.equals(FG_COLOR)) + throw new RuntimeException("Error in point "+p+": "+actual+" equals to foreground or background color"); + else + System.out.println("OK with foreground point "+p); + } + } + + public void checkStaticShape() throws Exception { + Point[] points = new Point[4]; + + Dimension size = window.getSize(); + int xFactor = (int) Math.floor(size.getWidth()/STATIC_STEP)-1; + int yFactor = (int) Math.floor(size.getHeight()/STATIC_STEP)-1; + + // background + points[0] = new Point((STATIC_STEP+STATIC_WIDTH)/2, (STATIC_STEP+STATIC_WIDTH)/2); + points[1] = new Point(STATIC_STEP*xFactor+(STATIC_STEP+STATIC_WIDTH)/2, STATIC_STEP*yFactor+(STATIC_STEP+STATIC_WIDTH)/2); + points[2] = new Point((STATIC_STEP+STATIC_WIDTH)/2, STATIC_STEP*yFactor+(STATIC_STEP+STATIC_WIDTH)/2); + points[3] = new Point(STATIC_STEP*xFactor+(STATIC_STEP+STATIC_WIDTH)/2, (STATIC_STEP+STATIC_WIDTH)/2); + checkShape(points, true); + + // foreground + if (opacity < 1.0f){ + checkTranslucentShape(); + } else { + points[0] = new Point((STATIC_WIDTH) / 2, (STATIC_WIDTH) / 2); + points[1] = new Point(STATIC_STEP * xFactor + (STATIC_WIDTH) / 2, STATIC_STEP * yFactor + (STATIC_WIDTH) / 2); + points[2] = new Point((STATIC_WIDTH) / 2, STATIC_STEP * yFactor + (STATIC_WIDTH) / 2); + points[3] = new Point(STATIC_STEP * xFactor + (STATIC_WIDTH) / 2, (STATIC_WIDTH) / 2); + checkShape(points, false); + } + } + + public void checkDynamicShape() throws Exception { + Point[] points = new Point[4]; + + Dimension size = window.getSize(); + + int blockSizeX = (int) (size.getWidth() / 17); + int blockSizeY = (int) (size.getHeight() / 17); + + // background + points[0] = new Point((int) (blockSizeX * 5.5), (int) (blockSizeY * 5.5)); + points[1] = new Point((int) (size.getWidth() - blockSizeX * 5.5), (int) (size.getHeight() - blockSizeY * 5.5)); + points[2] = new Point((int) (blockSizeX * 5.5), (int) (size.getHeight() - blockSizeY * 5.5)); + points[3] = new Point((int) (size.getWidth() - blockSizeX * 5.5), (int) (blockSizeY * 5.5)); + checkShape(points, true); + + // foreground + if (opacity < 1.0f){ + checkTranslucentShape(); + } else { + points[0] = new Point(3 * blockSizeX, 3 * blockSizeY); + points[1] = new Point(14 * blockSizeX, 14 * blockSizeY); + points[2] = new Point(3 * blockSizeX, 14 * blockSizeY); + points[3] = new Point(14 * blockSizeX, 3 * blockSizeY); + checkShape(points, false); + } + } + + public void checkShape(Point[] points, boolean areBackgroundPoints) throws Exception { + + Point location = window.getLocationOnScreen(); + + for (Point p : points) { + p.translate(location.x, location.y); + if (areBackgroundPoints) { + if (!robot.getPixelColor(p.x, p.y).equals(BG_COLOR)) + throw new RuntimeException("Background point " + p + " color " + robot.getPixelColor(p.x, p.y) + + " does not equal to background color " + BG_COLOR); + else + System.out.println("OK with background point " + p); + } else { + if (robot.getPixelColor(p.x, p.y).equals(BG_COLOR)) + throw new RuntimeException("Foreground point " + p + + " equals to background color " + BG_COLOR); + else + System.out.println("OK with foreground point " + p); + } + } + } + + public void initBackgroundFrame() { + background = new Frame(); + background.setUndecorated(true); + background.setBackground(BG_COLOR); + background.setSize(500, 500); + background.setLocation(dl, dl); + background.setVisible(true); + } + + public void initGUI() { + if (windowClass.equals(Frame.class)) { + window = new Frame(); + ((Frame) window).setUndecorated(true); + } else if (windowClass.equals(Dialog.class)) { + window = new Dialog(background); + ((Dialog) window).setUndecorated(true); + } else { + window = new Window(background); + } + + window.setBackground(FG_COLOR); + componentsContainer = new Panel(); + window.add(componentsContainer, BorderLayout.CENTER); + window.setLocation(2 * dl, 2 * dl); + window.setSize(255, 255); + if (opacity < 1.0f) + window.setOpacity(opacity); + window.addComponentListener(new ComponentAdapter() { + public void componentResized(ComponentEvent e) { + applyShape(); + } + }); + applyShape(); + window.setVisible(true); + applyAppDragNResizeSupport(); + window.toFront(); + } +}