--- /dev/null 2016-07-12 17:05:50.000000000 +0530 +++ new/test/java/awt/Dialog/NestedDialogs/Modal/NestedModalDialogTest.java 2016-07-12 17:05:50.000000000 +0530 @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2011, 2016 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. + */ + + /* + @test 8155740 + @summary See : Events: actionPerformed() method not + called when it is button is clicked (system load related) + @summary com.apple.junit.java.awt.Frame + @library ../../../regtesthelpers + @build VisibilityValidator + @build Util + @build Waypoint + @run main NestedModalDialogTest + */ +////////////////////////////////////////////////////////////////////////////// +// NestedModalDialogTest.java +// The test launches a parent frame. From this parent frame it launches a modal +// dialog. From the modal dialog it launches a second modal dialog with a text +// field in it and tries to write into the text field. The test succeeds if you +// are successfully able to write into this second Nested Modal Dialog +////////////////////////////////////////////////////////////////////////////// +// classes necessary for this test + +import java.awt.*; +import java.awt.event.*; +import java.util.Enumeration; + +import test.java.awt.regtesthelpers.Waypoint; +import test.java.awt.regtesthelpers.VisibilityValidator; +import test.java.awt.regtesthelpers.Util; + +public class NestedModalDialogTest { + + Waypoint[] event_checkpoint = new Waypoint[3]; + VisibilityValidator[] win_checkpoint = new VisibilityValidator[2]; + + IntermediateDialog interDiag; + TextDialog txtDiag; + + // Global variables so the robot thread can locate things. + Button[] robot_button = new Button[2]; + TextField robot_text = null; + static Robot _robot = null; + + /* + * @throws InterruptedException + * @throws WaypointException + */ + public void testModalDialogs() throws Exception { + Frame frame = null; + String result = ""; + Robot robot = getRobot(); + + event_checkpoint[0] = new Waypoint(); // "-Launch 1-" + event_checkpoint[1] = new Waypoint(); // "-Launch 2-" + + // Thread.currentThread().setName("NestedModalDialogTest Thread"); + // launch first frame with firstButton + frame = new StartFrame(); + VisibilityValidator.setVisibleAndConfirm(frame); + Util.clickOnComp(robot_button[0], robot); + + // Dialog must be created and onscreen before we proceed. + // The event_checkpoint waits for the Dialog to be created. + // The win_checkpoint waits for the Dialog to be visible. + event_checkpoint[0].requireClear("TestFrame actionPerformed() never " + + "called, see "); + win_checkpoint[0].requireVisible(); + Util.clickOnComp(robot_button[1], robot); + + // Again, the Dialog must be created and onscreen before we proceed. + // The event_checkpoint waits for the Dialog to be created. + // The win_checkpoint waits for the Dialog to be visible. + event_checkpoint[1].requireClear("IntermediateDialog actionPerformed() " + + "never called, see "); + win_checkpoint[1].requireVisible(); + Util.clickOnComp(robot_text, robot); + + // I'm really not sure whether the click is needed for focus + // but since it's asynchronous, as is the actually gaining of focus + // we might as well do our best + try { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + } + }); + } catch (Exception e) { + } + + robot.keyPress(KeyEvent.VK_SHIFT); + + robot.keyPress(KeyEvent.VK_H); + robot.waitForIdle(); + robot.keyRelease(KeyEvent.VK_H); + + robot.keyRelease(KeyEvent.VK_SHIFT); + + robot.keyPress(KeyEvent.VK_E); + robot.waitForIdle(); + robot.keyRelease(KeyEvent.VK_E); + + robot.keyPress(KeyEvent.VK_L); + robot.waitForIdle(); + robot.keyRelease(KeyEvent.VK_L); + + robot.keyPress(KeyEvent.VK_L); + robot.waitForIdle(); + robot.keyRelease(KeyEvent.VK_L); + + robot.keyPress(KeyEvent.VK_O); + robot.waitForIdle(); + robot.keyRelease(KeyEvent.VK_O); + + // + // NOTE THAT WE MAY HAVE MORE SYNCHRONIZATION WORK TO DO HERE. + // CURRENTLY THERE IS NO GUARANTEE THAT THE KEYEVENT THAT THAT + // TYPES THE 'O' HAS BEEN PROCESSED BEFORE WE GET THE RESULT + // + // This is a (lame) attempt at waiting for the last typeKey events to + // propagate. It's not quite right because robot uses + // CGRemoteOperations, which are asynchronous. But that's why I put in + // the pause + try { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + } + }); + } catch (Exception e) { + } + + // Need to call this before the dialog that robot_text is in is disposed + result = robot_text.getText(); + + Thread.sleep(50); // shouldn't need this, but pause adds stability + // Click Close box of modal dialog with textField + Util.clickOnComp(txtDiag, robot); + + Thread.sleep(50); // shouldn't need this, but pause adds stability + // Click Close box of intermediate modal dialog + Util.clickOnComp(interDiag, robot); + + Thread.sleep(50); // shouldn't need this, but pause adds stability + // Click Close box of intermediate modal dialog + Util.clickOnComp(frame, robot); + + String expected = "Hello"; + } + + private static Robot getRobot() { + if (_robot == null) { + try { + _robot = new Robot(); + } catch (AWTException e) { + throw new RuntimeException("Robot creation failed"); + } + } + return _robot; + } + + //////////////////// Start Frame /////////////////// + /** + * Launches the first frame with a button in it + */ + class StartFrame extends Frame { + + /** + * Constructs a new instance. + */ + public StartFrame() { + super("First Frame"); + setLayout(new GridBagLayout()); + setLocation(375, 200); + setSize(271, 161); + Button but = new Button("Make Intermediate"); + but.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(ActionEvent e) { + interDiag = new IntermediateDialog(StartFrame.this); + win_checkpoint[0] = new VisibilityValidator(interDiag); + interDiag.setSize(300, 200); + + // may need listener to watch this move. + interDiag.setLocation(getLocationOnScreen()); + interDiag.pack(); + event_checkpoint[0].clear(); + interDiag.setVisible(true); + } + }); + Panel pan = new Panel(); + pan.add(but); + add(pan); + robot_button[0] = but; + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + setVisible(false); + dispose(); + } + }); + } + } + + ///////////////////////////// MODAL DIALOGS ///////////////////////////// + /* A Dialog that launches a sub-dialog */ + class IntermediateDialog extends Dialog { + + Dialog m_parent; + + public IntermediateDialog(Frame parent) { + super(parent, "Intermediate Modal", true /*Modal*/); + m_parent = this; + Button but = new Button("Make Text"); + but.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(ActionEvent e) { + txtDiag = new TextDialog(m_parent); + win_checkpoint[1] = new VisibilityValidator(txtDiag); + txtDiag.setSize(300, 100); + event_checkpoint[1].clear(); + txtDiag.setVisible(true); + } + }); + Panel pan = new Panel(); + pan.add(but); + add(pan); + pack(); + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + setVisible(false); + dispose(); + } + }); + + // The robot needs to know about us, so set global + robot_button[1] = but; + } + } + + /* A Dialog that just holds a text field */ + class TextDialog extends Dialog { + + public TextDialog(Dialog parent) { + super(parent, "Modal Dialog", true /*Modal*/); + TextField txt = new TextField("", 10); + Panel pan = new Panel(); + pan.add(txt); + add(pan); + pack(); + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + setVisible(false); + dispose(); + } + }); + + // The robot needs to know about us, so set global + robot_text = txt; + } + } + + public static void main(String[] args) throws RuntimeException, Exception { + try { + new NestedModalDialogTest().testModalDialogs(); + } catch (Exception e) { + throw new RuntimeException("NestedModalDialogTest object creation " + + "failed"); + } + } +} --- /dev/null 2016-07-12 17:05:51.000000000 +0530 +++ new/test/java/awt/Dialog/NestedDialogs/Modeless/NestedModelessDialogTest.java 2016-07-12 17:05:51.000000000 +0530 @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2011, 2016 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. + */ + + /* + @test 8155740 + @summary See : Events: actionPerformed() method not + called when it is button is clicked (system load related) + @summary com.apple.junit.java.awt.Frame + @library ../../../regtesthelpers + @build VisibilityValidator + @build Util + @build Waypoint + @run main NestedModelessDialogTest + */ +///////////////////////////////////////////////////////////////////////////// +// NestedModelessDialogTest.java +// The test launches a parent frame. From this parent frame it launches a modal +// dialog. From the modal dialog it launches a modeless dialog with a text +// field in it and tries to write into the text field. The test succeeds if you +// are successfully able to write into this Nested Modeless Dialog +///////////////////////////////////////////////////////////////////////////// +// classes necessary for this test +import java.awt.*; +import java.awt.event.*; +import java.util.Enumeration; + +import test.java.awt.regtesthelpers.Util; +import test.java.awt.regtesthelpers.VisibilityValidator; +import test.java.awt.regtesthelpers.Waypoint; + +public class NestedModelessDialogTest { + + Waypoint[] event_checkpoint = new Waypoint[3]; + VisibilityValidator[] win_checkpoint = new VisibilityValidator[2]; + + IntermediateDialog interDiag; + TextDialog txtDiag; + + // Global variables so the robot thread can locate things. + Button[] robot_button = new Button[2]; + TextField robot_text = null; + static Robot _robot = null; + + /** + * Get called by test harness + * + * @throws Exception + */ + public void testModelessDialogs() throws Exception { + Frame frame = null; + String result = ""; + Robot robot = getRobot(); + + event_checkpoint[0] = new Waypoint(); // "-Launch 1-" + event_checkpoint[1] = new Waypoint(); // "-Launch 2-" + + // launch first frame with fistButton + frame = new StartFrame(); + VisibilityValidator.setVisibleAndConfirm(frame); + Util.clickOnComp(robot_button[0], robot); + + // Dialog must be created and onscreen before we proceed. + // The event_checkpoint waits for the Dialog to be created. + // The win_checkpoint waits for the Dialog to be visible. + event_checkpoint[0].requireClear(); + win_checkpoint[0].requireVisible(); + Util.clickOnComp(robot_button[1], robot); + + // Again, the Dialog must be created and onscreen before we proceed. + // The event_checkpoint waits for the Dialog to be created. + // The win_checkpoint waits for the Dialog to be visible. + event_checkpoint[1].requireClear(); + win_checkpoint[1].requireVisible(); + Util.clickOnComp(robot_text, robot); + + // I'm really not sure whether the click is needed for focus + // but since it's asynchronous, as is the actually gaining of focus + // we might as well do our best + try { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + } + }); + } catch (Exception e) { + } + + robot.keyPress(KeyEvent.VK_SHIFT); + + robot.keyPress(KeyEvent.VK_H); + robot.waitForIdle(); + robot.keyRelease(KeyEvent.VK_H); + + robot.keyRelease(KeyEvent.VK_SHIFT); + + robot.keyPress(KeyEvent.VK_E); + robot.waitForIdle(); + robot.keyRelease(KeyEvent.VK_E); + + robot.keyPress(KeyEvent.VK_L); + robot.waitForIdle(); + robot.keyRelease(KeyEvent.VK_L); + + robot.keyPress(KeyEvent.VK_L); + robot.waitForIdle(); + robot.keyRelease(KeyEvent.VK_L); + + robot.keyPress(KeyEvent.VK_O); + robot.waitForIdle(); + robot.keyRelease(KeyEvent.VK_O); + + // + // NOTE THAT WE MAY HAVE MORE SYNCHRONIZATION WORK TO DO HERE. + // CURRENTLY THERE IS NO GUARANTEE THAT THE KEYEVENT THAT THAT + // TYPES THE 'O' HAS BEEN PROCESSED BEFORE WE GET THE RESULT + // + // This is a (lame) attempt at waiting for the last typeKey events to + // propagate. It's not quite right because robot uses + // CGRemoteOperations, which are asynchronous. But that's why I put in + // the Thread.sleep + try { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + } + }); + } catch (Exception e) { + } + + // Need to call this before the dialog that robot_text is in is disposed + result = robot_text.getText(); + + Thread.sleep(50); // Thread.sleep adds stability + // Click Close box of modeless dialog with textField + Util.clickOnComp(txtDiag, robot); + + Thread.sleep(50); // Thread.sleep adds stability + // Click Close box of intermediate modal dialog + Util.clickOnComp(interDiag, robot); + + Thread.sleep(50); // Thread.sleep adds stability + // Click Close box of intermediate modal dialog + Util.clickOnComp(frame, robot); + + String expected = "Hello"; + } + + private static Robot getRobot() { + if (_robot == null) { + try { + _robot = new Robot(); + } catch (AWTException e) { + throw new RuntimeException("Robot creation failed"); + } + } + return _robot; + } + + //////////////////// Start Frame /////////////////// + /** + * Launches the first frame with a button in it + */ + class StartFrame extends Frame { + + /** + * Constructs a new instance. + */ + public StartFrame() { + super("First Frame"); + setLayout(new GridBagLayout()); + setLocation(375, 200); + setSize(271, 161); + Button but = new Button("Make Intermediate"); + but.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(ActionEvent e) { + interDiag = new IntermediateDialog(StartFrame.this); + win_checkpoint[0] = new VisibilityValidator(interDiag); + interDiag.setSize(300, 200); + + // may need listener to watch this move. + interDiag.setLocation(getLocationOnScreen()); + interDiag.pack(); + event_checkpoint[0].clear(); + interDiag.setVisible(true); + } + }); + Panel pan = new Panel(); + pan.add(but); + add(pan); + robot_button[0] = but; + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + setVisible(false); + dispose(); + } + }); + } + } + + ///////////////////////////// VARIOUS DIALOGS ////////////////////////// + /* A Dialog that launches a sub-dialog */ + class IntermediateDialog extends Dialog { + + Dialog m_parent; + + public IntermediateDialog(Frame parent) { + super(parent, "Intermediate Modal", true /*Modal*/); + m_parent = this; + Button but = new Button("Make Text"); + but.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(ActionEvent e) { + txtDiag = new TextDialog(m_parent); + win_checkpoint[1] = new VisibilityValidator(txtDiag); + txtDiag.setSize(300, 100); + event_checkpoint[1].clear(); + txtDiag.setVisible(true); + } + }); + Panel pan = new Panel(); + pan.add(but); + add(pan); + pack(); + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + setVisible(false); + dispose(); + } + }); + + // The robot needs to know about us, so set global + robot_button[1] = but; + } + } + + /* A Dialog that just holds a text field */ + class TextDialog extends Dialog { + + public TextDialog(Dialog parent) { + super(parent, "Modeless Dialog", false /*Modeless*/); + TextField txt = new TextField("", 10); + Panel pan = new Panel(); + pan.add(txt); + add(pan); + pack(); + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + setVisible(false); + dispose(); + } + }); + + // The robot needs to know about us, so set global + robot_text = txt; + } + } + + public static void main(String[] args) throws RuntimeException { + try { + new NestedModelessDialogTest().testModelessDialogs(); + } catch (Exception e) { + throw new RuntimeException("NestedModelessDialogTest object " + + "creation failed"); + } + } +} --- /dev/null 2016-07-12 17:05:52.000000000 +0530 +++ new/test/java/awt/regtesthelpers/VisibilityValidator.java 2016-07-12 17:05:51.000000000 +0530 @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2011, 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. + */ + + /* + * @summary Utility routines that wait for a window to be displayed or for +colors to be visible + * @summary com.apple.junit.utils + */ +package test.java.awt.regtesthelpers; + +import java.awt.*; +import java.awt.event.*; + +//import junit.framework.Assert; +public class VisibilityValidator { + + // Wait up to five seconds for our window events + static final int SETUP_PERIOD = 5000; + static final boolean DEBUG = false; + + volatile Window win = null; + boolean activated = false; + boolean opened = false; + boolean focused = false; + volatile boolean valid = false; + + // + // Utility functions that encapsulates normal usage patterns + // + public static void setVisibleAndConfirm(Frame testframe) throws Exception { + setVisibleAndConfirm(testframe, "Could not confirm test frame was " + + "visible"); + } + + public static void setVisibleAndConfirm(Frame testframe, String msg) + throws Exception { + if (testframe.isVisible()) { + throw new RuntimeException("Frame is already visible"); + } + + VisibilityValidator checkpoint = new VisibilityValidator(testframe); + testframe.setVisible(true); + checkpoint.requireVisible(); + if (!checkpoint.isValid()) { + //System.err.println(msg); + throw new Exception("Frame not visible after " + SETUP_PERIOD + + " milliseconds"); + } + } + + // + // Add listeners to the window + // + public VisibilityValidator(Window win) { + this.win = win; + WindowAdapter watcher = new WindowAdapter() { + public void windowOpened(WindowEvent e) { + doOpen(); + } + + public void windowActivated(WindowEvent e) { + doActivate(); + } + + public void windowGainedFocus(WindowEvent e) { + doGainedFocus(); + } + }; + + win.addWindowListener(watcher); + win.addWindowFocusListener(watcher); + } + + // Make the window visible + // + // The only way to make it through this routine is for the window to + // generate BOTH a windowOpened, a windowActivated event and a + // windowGainedFocus, or to timeout. + // + synchronized public void requireVisible() { + int tries = 0; + + // wait for windowOpened and windowActivated events + try { + while ((opened == false) + || (activated == false) + || (focused == false)) { + if (tries < 4) { + tries += 1; + wait(SETUP_PERIOD); + } else { + break; + } + } + + if (opened && activated) { + valid = true; + } else { + valid = false; + } + } catch (InterruptedException ix) { + valid = false; + } + + // Extra-super paranoid checks + if (win.isVisible() == false) { + valid = false; + } + + if (win.isShowing() == false) { + valid = false; + } + + if (win.isFocused() == false) { + valid = false; + } + + if (DEBUG) { + if (!isValid()) { + System.out.println("\tactivated:" + new Boolean(activated)); + System.out.println("\topened:" + new Boolean(opened)); + System.out.println("\tfocused:" + new Boolean(focused)); + System.out.println("\tvalid:" + new Boolean(valid)); + System.out.println("\tisVisible():" + + new Boolean(win.isVisible())); + System.out.println("\tisShowing():" + + new Boolean(win.isShowing())); + System.out.println("\tisFocused():" + + new Boolean(win.isFocused())); + } + } + + } + + synchronized void doOpen() { + opened = true; + notify(); + } + + synchronized void doActivate() { + activated = true; + notify(); + } + + synchronized void doGainedFocus() { + focused = true; + notify(); + } + + public boolean isValid() { + return valid; + } + + public boolean isClear() { + return valid; + } + + volatile static Robot robot = null; + + // utility function that waits until a Component is shown with the + // appropriate color + public static boolean waitForColor(Component c, + Color expected) throws AWTException, + InterruptedException { + Dimension dim = c.getSize(); + int xOff = dim.width / 2; + int yOff = dim.height / 2; + return waitForColor(c, xOff, yOff, expected); + } + + // utility function that waits for 5 seconds for Component to be shown with + // the appropriate color + public static boolean waitForColor(Component c, + int xOff, + int yOff, + Color expected) throws AWTException, InterruptedException { + return waitForColor(c, xOff, yOff, expected, 5000L); + } + + // utility function that waits until a Component is up with the appropriate + // color + public static boolean waitForColor(Component c, + int xOff, + int yOff, + Color expected, + long timeout) throws AWTException, InterruptedException { + Point p = c.getLocationOnScreen(); + int x = (int) p.getX() + xOff; + int y = (int) p.getY() + yOff; + return waitForColor(x, y, expected, timeout); + } + + // utility function that waits until specific screen coords have the + // appropriate color + public static boolean waitForColor(int locX, + int locY, + Color expected, + long timeout) throws AWTException, InterruptedException { + if (robot == null) { + robot = new Robot(); + } + + long endtime = System.currentTimeMillis() + timeout; + while (endtime > System.currentTimeMillis()) { + if (colorMatch(robot.getPixelColor(locX, locY), expected)) { + return true; + } + Thread.sleep(50); + } + + return false; + } + + // utility function that asserts that two colors are similar to each other + public static void assertColorEquals(final String message, + final Color actual, + final Color expected) { + System.out.println("actual color: " + actual); + System.out.println("expect color: " + expected); + //Assert.assertTrue(message, colorMatch(actual, expected)); + } + + // determines if two colors are close in hue and brightness + public static boolean colorMatch(final Color actual, final Color expected) { + final float[] actualHSB = getHSB(actual); + final float[] expectedHSB = getHSB(expected); + + final float actualHue = actualHSB[0]; + final float expectedHue = expectedHSB[0]; + final boolean hueMatched = closeMatchHue(actualHue, expectedHue, 0.17f); + //System.out.println("hueMatched? " + hueMatched); + final float actualBrightness = actualHSB[2]; + final float expectedBrightness = expectedHSB[2]; + final boolean brightnessMatched = closeMatch(actualBrightness, + expectedBrightness, 0.15f); + //System.out.println("brightnessMatched? " + brightnessMatched); + + // check to see if the brightness was so low or so high that the hue + // got clamped to red + if (brightnessMatched && !hueMatched) { + return (expectedBrightness < 0.15f); + } + + return brightnessMatched && hueMatched; + } + + static float[] getHSB(final Color color) { + final float[] hsb = new float[3]; + Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), hsb); + return hsb; + } + + // matches hues from 0.0 to 1.0, accounting for wrap-around at the 1.0/0.0 + // boundry + static boolean closeMatchHue(final float actual, + final float expected, + final float tolerance) { + if (closeMatch(actual, expected, tolerance)) { + return true; + } + + // all that remains is the overflow and underflow cases + final float expectedHigh = expected + tolerance; + final float expectedLow = expected - tolerance; + + if (expectedHigh > 1.0f) { + // expected is too high, and actual was too low + //System.out.println("\thue expected too high, actual too low"); + return closeMatch(actual + 0.5f, expected - 0.5f, tolerance); + } + + if (expectedLow < 0.0f) { + // expected is too low, and actual was too high + //System.out.println("\thue expected too low, actual too high"); + return closeMatch(actual - 0.5f, expected + 0.5f, tolerance); + } + + //System.out.println("\tcloseMatchHue? " + false); + return false; + } + + static boolean closeMatch(final float actual, + final float expected, + final float tolerance) { + return (expected + tolerance) > actual && (expected - tolerance) < actual; + } +} --- /dev/null 2016-07-12 17:05:52.000000000 +0530 +++ new/test/java/awt/regtesthelpers/Waypoint.java 2016-07-12 17:05:52.000000000 +0530 @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2011, 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. + */ + + /* + * @summary This is a utility for coordinating the flow of events on different + threads. + * @summary com.apple.junit.utils + */ +package test.java.awt.regtesthelpers; + +public class Waypoint { + + static final String MSG = "Waypoint timed out"; + // Wait up to five seconds for our clear() to be called + static final int TIMEOUT = 5000; + boolean clear = false; + + public Waypoint() { + + } + + // + // Pause for either TIMEOUT millis or until clear() is called + // + synchronized public void requireClear() throws RuntimeException { + requireClear(MSG, TIMEOUT); + } + + synchronized public void requireClear(long timeout) + throws RuntimeException { + requireClear(MSG, timeout); + } + + synchronized public void requireClear(String timeOutMsg) + throws RuntimeException { + requireClear(timeOutMsg, TIMEOUT); + } + + synchronized public void requireClear(String timeOutMsg, long timeout) + throws RuntimeException { + long endtime = System.currentTimeMillis() + timeout; + try { + while (isClear() == false) { + if (System.currentTimeMillis() < endtime) { + wait(200); + } else { + break; + } + } + + if (!isClear()) { + throw new RuntimeException(timeOutMsg); + } + } catch (InterruptedException ix) { + } + } + + // + // Called when it is valid to procede past the waypoint + // + synchronized public void clear() { + clear = true; + notify(); + } + + // + // Should be checked after a call to requireClear() to make + // sure that we did not time out. + // + synchronized public boolean isClear() { + return clear; + } + + synchronized public boolean isValid() { + return clear; + } + + // + // For re-use of a waypoint. Be careful. + // + synchronized public void reset() { + clear = false; + } + +}