diff --git a/test/jdk/java/awt/Choice/ChoiceSelectTest.java b/test/jdk/java/awt/Choice/ChoiceSelectTest.java new file mode 100644 index 00000000000..cf5b2e6d114 --- /dev/null +++ b/test/jdk/java/awt/Choice/ChoiceSelectTest.java @@ -0,0 +1,174 @@ +/* + * Copyright (c) 1998, 2023, 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.Choice; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Panel; + +/* + * @test + * @bug 4115139 4128213 + * @summary Tests that the (rather bizarre) rules for handling selection + * in Choice components are implemented as documented in + * "The Java Class Libraries 2nd Edition" + * @key headful + */ + +public class ChoiceSelectTest extends Panel { + final Choice c; + + public ChoiceSelectTest() { + setLayout(new FlowLayout()); + c = new Choice(); + add(c); + } + + private void test() { + testAddition(); + testInsertion(); + testRemoval(); + testIndices(); + } + + public void testAddition() { + c.removeAll(); + + // check that after first item added selection is zero + c.addItem("zero"); + if (c.getSelectedIndex() != 0) { + throw new SelectionException("selection wrong after first add"); + } + + // check that selection doesn't change for subsequent adds + c.addItem("one"); + c.select(1); + c.addItem("two"); + if (c.getSelectedIndex() != 1) { + throw new SelectionException("selection wrong after subsequent add"); + } + } + + public void testInsertion() { + c.removeAll(); + + // check that after first item inserted selection is zero + c.insert("zero", 0); + if (c.getSelectedIndex() != 0) { + throw new SelectionException("selection wrong after first insert"); + } + + // check that if selected item shifted, selection goes to zero + c.insert("three", 1); + c.select(1); + c.insert("one", 1); + if (c.getSelectedIndex() != 0) { + throw new SelectionException("selection wrong after selected item shifted"); + } + + // check that if selected item not shifted, selection stays the same + c.select(1); + c.insert("two", 2); + if (c.getSelectedIndex() != 1) { + throw new SelectionException("selection wrong after item inserted after selection"); + } + } + + public void testRemoval() { + c.removeAll(); + + // check that if removing selected item, selection goes to 0 + c.add("zero"); + c.add("one"); + c.add("two"); + c.select(2); + c.remove(2); + if (c.getSelectedIndex() != 0) { + throw new SelectionException("selection wrong after removing selected item"); + } + + // check that if removing item before the selection + // the selected index is updated + c.add("two"); + c.add("three"); + c.select(3); + c.remove(1); + if (c.getSelectedIndex() != 2) { + throw new SelectionException("selection wrong after removing item before it"); + } + } + + public void testIndices() { + c.removeAll(); + + c.addItem("zero"); + c.addItem("one"); + c.addItem("two"); + c.addItem("three"); + c.addItem("four"); + c.addItem("five"); + + // Test selection of negative index + try { + c.select(-1); + throw new SelectionException("Negative Index Test FAILED"); + } catch (IllegalArgumentException expected) {} + + // Test selection of zero index + try { + c.select(0); + } catch (IllegalArgumentException iae) { + throw new SelectionException("Zero Index Test FAILED", iae); + } + + // Test selection of maximum index + try { + c.select(5); + } catch (IllegalArgumentException iae) { + throw new SelectionException("Maximum Index Test FAILED", iae); + } + + // Test selection of index that is too large + try { + c.select(6); + throw new SelectionException("Greater than Maximum Index Test FAILED"); + } catch (IllegalArgumentException expected) {} + } + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> new ChoiceSelectTest().test()); + } + + class SelectionException extends RuntimeException { + SelectionException(String msg, Throwable cause) { + super(msg, cause); + System.out.println( + "Selection item is '" + c.getSelectedItem() + + "' at index " + c.getSelectedIndex()); + } + + SelectionException(String msg) { + this(msg, null); + } + } +} diff --git a/test/jdk/java/awt/Component/Displayable.java b/test/jdk/java/awt/Component/Displayable.java new file mode 100644 index 00000000000..0c4969bb595 --- /dev/null +++ b/test/jdk/java/awt/Component/Displayable.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 1998, 2023, 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.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Label; +import java.awt.Panel; + +/* + * @test + * @key headful + * @summary automated test for "displayable" property on Component + */ + +public class Displayable extends Panel { + Label status = new Label("Displayable Test started..."); + + public void init() { + setLayout(new BorderLayout()); + add("South", status); + + LightDisplayable light = new LightDisplayable(); + shouldNotBeDisplayable(light, "before added to container "); + + HeavyDisplayable heavy = new HeavyDisplayable(); + shouldNotBeDisplayable(heavy, "before added to container "); + + add("West", light); + add("East", heavy); + + statusMessage("Displayable test completed successfully."); + } + + protected void addImpl(Component child, Object constraints, int index) { + super.addImpl(child, constraints, index); + if (isDisplayable()) { + shouldBeDisplayable(child, "after added to displayable container "); + } else { + shouldNotBeDisplayable(child, "after added to undisplayable container "); + } + } + + public void remove(Component child) { + super.remove(child); + shouldNotBeDisplayable(child, "after removed from displayable container "); + } + + public void statusMessage(String msg) { + status.setText(msg); + status.invalidate(); + validate(); + } + + public static void shouldNotBeDisplayable(Component c, String why) { + if (c.isDisplayable()) { + throw new RuntimeException("Component is displayable "+why+c.getName()); + } + } + + public static void shouldBeDisplayable(Component c, String why) { + if (!c.isDisplayable()) { + throw new RuntimeException("Component is NOT displayable "+why+c.getName()); + } + } + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + Frame f = new Frame(); + try { + Displayable test = new Displayable(); + test.init(); + f.add("North", test); + f.pack(); + } finally { + f.dispose(); + } + }); + } +} + +class LightDisplayable extends Component { + + public Dimension getPreferredSize() { + return new Dimension(50,50); + } + + public void paint(Graphics g) { + Dimension size = getSize(); + g.setColor(Color.blue); + g.fillRect(0, 0, size.width, size.height); + super.paint(g); + } + + public void addNotify() { + Displayable.shouldNotBeDisplayable(this, "before addNotify "); + super.addNotify(); + Displayable.shouldBeDisplayable(this, "after addNotify "); + } + + public void removeNotify() { + Displayable.shouldBeDisplayable(this, "before removeNotify "); + super.removeNotify(); + Displayable.shouldNotBeDisplayable(this, "after removeNotify "); + } +} + +class HeavyDisplayable extends Panel { + + public Dimension getPreferredSize() { + return new Dimension(50, 50); + } + + public void paint(Graphics g) { + Dimension size = getSize(); + g.setColor(Color.black); + g.fillRect(0, 0, size.width, size.height); + super.paint(g); + } + + public void addNotify() { + Displayable.shouldNotBeDisplayable(this, "before addNotify "); + super.addNotify(); + Displayable.shouldBeDisplayable(this, "after addNotify "); + } + + public void removeNotify() { + Displayable.shouldBeDisplayable(this, "before removeNotify "); + super.removeNotify(); + Displayable.shouldNotBeDisplayable(this, "after removeNotify "); + } +} diff --git a/test/jdk/java/awt/Focus/TestWindowsLFFocus.java b/test/jdk/java/awt/Focus/TestWindowsLFFocus.java new file mode 100644 index 00000000000..8dd27f0a649 --- /dev/null +++ b/test/jdk/java/awt/Focus/TestWindowsLFFocus.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2002, 2023, 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 javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.WindowConstants; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; + +/* + * @test + * @bug 4749659 + * @summary Tests that popup menu doesn't steal focus from top-level + * @key headful + */ + +public class TestWindowsLFFocus { + static volatile boolean actionFired; + + static JFrame frame; + static JMenuBar bar; + static JMenuItem item; + static volatile Point frameLoc; + + public static void main(String[] args) throws Exception { + for (UIManager.LookAndFeelInfo lookAndFeel : UIManager.getInstalledLookAndFeels()) { + UIManager.setLookAndFeel(lookAndFeel.getClassName()); + test(); + } + + System.err.println("PASSED"); + } + + private static void test() throws Exception { + try { + SwingUtilities.invokeAndWait(() -> { + actionFired = false; + frame = new JFrame(); + bar = new JMenuBar(); + frame.setJMenuBar(bar); + JMenu menu = new JMenu("menu"); + bar.add(menu); + item = new JMenuItem("item"); + menu.add(item); + item.addActionListener(e -> actionFired = true); + + frame.getContentPane().add(new JButton("none")); + frame.setBounds(100, 100, 100, 100); + frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + frame.setVisible(true); + }); + + Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(50); + + robot.waitForIdle(); + robot.delay(1000); + + SwingUtilities.invokeAndWait(() -> { + Point location = frame.getLocationOnScreen(); + Insets insets = frame.getInsets(); + + location.translate(insets.left + 15, insets.top + bar.getHeight() / 2); + + frameLoc = location; + }); + + robot.mouseMove(frameLoc.x, frameLoc.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + robot.delay(1000); + + SwingUtilities.invokeAndWait(() -> { + Point location = new Point(frameLoc); + location.y += bar.getHeight() / 2 + item.getHeight() / 2; + + frameLoc = location; + }); + + robot.mouseMove(frameLoc.x, frameLoc.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + robot.waitForIdle(); + robot.delay(500); + + if (!actionFired) { + throw new RuntimeException("Menu closed without action"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff --git a/test/jdk/java/awt/geom/HitTest/PathHitTest.java b/test/jdk/java/awt/geom/HitTest/PathHitTest.java new file mode 100644 index 00000000000..930e7f764a6 --- /dev/null +++ b/test/jdk/java/awt/geom/HitTest/PathHitTest.java @@ -0,0 +1,392 @@ +/* + * Copyright (c) 1999, 2023, 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.BorderLayout; +import java.awt.Canvas; +import java.awt.Choice; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Panel; +import java.awt.Polygon; +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.Area; +import java.awt.geom.Ellipse2D; +import java.awt.geom.GeneralPath; +import java.awt.geom.Point2D; + +/* + * @test + * @bug 4210936 4214524 + * @summary Tests the results of the hit test methods on 3 different + * Shape objects - Polygon, Area, and GeneralPath. Both an + * automatic test for constraint compliance and a manual + * test for correctness are included in this one class. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main PathHitTest + */ + +/* + * @test + * @bug 4210936 4214524 + * @summary Tests the results of the hit test methods on 3 different + * Shape objects - Polygon, Area, and GeneralPath. Both an + * automatic test for constraint compliance and a manual + * test for correctness are included in this one class. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual PathHitTest manual + */ + +public class PathHitTest { + + public static final int BOXSIZE = 5; + public static final int BOXCENTER = 2; + public static final int TESTSIZE = 400; + public static final int NUMTESTS = (TESTSIZE + BOXSIZE - 1) / BOXSIZE; + + public static Shape[] testShapes = new Shape[5]; + public static String[] testNames = { + "Polygon", + "EvenOdd GeneralPath", + "NonZero GeneralPath", + "Area from EO GeneralPath", + "Area from NZ GeneralPath", + }; + + static { + GeneralPath gpeo = new GeneralPath(GeneralPath.WIND_EVEN_ODD); + Ellipse2D ell = new Ellipse2D.Float(); + Point2D center = new Point2D.Float(); + AffineTransform at = new AffineTransform(); + for (int i = 0; i < 360; i += 30) { + center.setLocation(100, 0); + at.setToTranslation(200, 200); + at.rotate(i * Math.PI / 180); + at.transform(center, center); + ell.setFrame(center.getX() - 50, center.getY() - 50, 100, 100); + gpeo.append(ell, false); + } + GeneralPath side = new GeneralPath(); + side.moveTo(0, 0); + side.lineTo(15, 10); + side.lineTo(30, 0); + side.lineTo(45, -10); + side.lineTo(60, 0); + append4sides(gpeo, side, 20, 20); + side.reset(); + side.moveTo(0, 0); + side.quadTo(15, 10, 30, 0); + side.quadTo(45, -10, 60, 0); + append4sides(gpeo, side, 320, 20); + side.reset(); + side.moveTo(0, 0); + side.curveTo(15, 10, 45, -10, 60, 0); + append4sides(gpeo, side, 20, 320); + + GeneralPath gpnz = new GeneralPath(GeneralPath.WIND_NON_ZERO); + gpnz.append(gpeo, false); + Polygon p = new Polygon(); + p.addPoint( 50, 50); + p.addPoint( 60, 350); + p.addPoint(250, 340); + p.addPoint(260, 150); + p.addPoint(140, 140); + p.addPoint(150, 260); + p.addPoint(340, 250); + p.addPoint(350, 60); + testShapes[0] = p; + testShapes[1] = gpeo; + testShapes[2] = gpnz; + testShapes[3] = new Area(gpeo); + testShapes[3].getPathIterator(null); + testShapes[4] = new Area(gpnz); + testShapes[4].getPathIterator(null); + } + + private static void append4sides(GeneralPath path, GeneralPath side, + double xoff, double yoff) { + AffineTransform at = new AffineTransform(); + at.setToTranslation(xoff, yoff); + for (int i = 0; i < 4; i++) { + path.append(side.getPathIterator(at), i != 0); + at.rotate(Math.toRadians(90), 30, 30); + } + } + + public static void main(String[] argv) throws Exception { + if (argv.length > 0 && argv[0].equals("manual")) { + PathHitTestManual.doManual(); + } else { + int totalerrs = 0; + for (int i = 0; i < testShapes.length; i++) { + totalerrs += testshape(testShapes[i], testNames[i]); + } + if (totalerrs != 0) { + throw new RuntimeException(totalerrs + + " constraint conditions violated!"); + } + } + } + + public static int testshape(Shape s, String name) { + int numerrs = 0; + long start = System.currentTimeMillis(); + for (int y = 0; y < TESTSIZE; y += BOXSIZE) { + for (int x = 0; x < TESTSIZE; x += BOXSIZE) { + boolean rectintersects = s.intersects(x, y, BOXSIZE, BOXSIZE); + boolean rectcontains = s.contains(x, y, BOXSIZE, BOXSIZE); + boolean pointcontains = s.contains(x + BOXCENTER, y + BOXCENTER); + if (rectcontains && !rectintersects) { + System.err.println("rect is contained " + + "but does not intersect!"); + numerrs++; + } + if (rectcontains && !pointcontains) { + System.err.println("rect is contained " + + "but center is not contained!"); + numerrs++; + } + if (pointcontains && !rectintersects) { + System.err.println("center is contained " + + "but rect does not intersect!"); + numerrs++; + } + } + } + long end = System.currentTimeMillis(); + System.out.println(name + " completed in " + + (end - start) + "ms with " + + numerrs + " errors"); + return numerrs; + } + + static class PathHitTestManual extends Panel { + private static final String INSTRUCTIONS = """ + This test displays the results of hit testing 5 different Shape + objects one at a time. + + You can switch between shapes using the Choice component located + at the bottom of the window. + + Each square in the test represents the + return values of the hit testing operators for that square region: + + yellow - not yet tested + translucent blue overlay - the shape being tested + + black - all outside + dark gray - rectangle intersects shape + light gray - rectangle intersects and center point is inside shape + white - rectangle is entirely contained in shape + red - some constraint was violated, including: + rectangle is contained, but center point is not + rectangle is contained, but rectangle.intersects is false + centerpoint is contained, but rectangle.intersects is false + + Visually inspect the results to see if they match the above table. + Note that it is not a violation for rectangles that are entirely + inside the path to be light gray instead of white since sometimes + the path is complex enough to make an exact determination expensive. + You might see this on the GeneralPath NonZero example where the + circles that make up the path cross over the interior of the shape + and cause the hit testing methods to guess that the rectangle is + not guaranteed to be contained within the shape. + """; + + PathHitTestCanvas phtc; + + public void init() { + setLayout(new BorderLayout()); + phtc = new PathHitTestCanvas(); + add("Center", phtc); + final Choice ch = new Choice(); + for (int i = 0; i < PathHitTest.testNames.length; i++) { + ch.add(PathHitTest.testNames[i]); + } + ch.addItemListener(e -> phtc.setShape(ch.getSelectedIndex())); + ch.select(0); + phtc.setShape(0); + add("South", ch); + } + + public void start() { + phtc.start(); + } + + public void stop() { + phtc.stop(); + } + + public static class PathHitTestCanvas extends Canvas implements Runnable { + public static final Color[] colors = { + /* contains? point in? intersects? */ + Color.black, /* NO NO NO */ + Color.darkGray, /* NO NO YES */ + Color.red, /* NO YES NO */ + Color.lightGray, /* NO YES YES */ + Color.red, /* YES NO NO */ + Color.red, /* YES NO YES */ + Color.red, /* YES YES NO */ + Color.white, /* YES YES YES */ + Color.yellow, /* used for untested points */ + }; + + public Dimension getPreferredSize() { + return new Dimension(TESTSIZE, TESTSIZE); + } + + public synchronized void start() { + if (!testdone) { + renderer = new Thread(this); + renderer.setPriority(Thread.MIN_PRIORITY); + renderer.start(); + } + } + + public synchronized void stop() { + renderer = null; + } + + private Thread renderer; + private int shapeIndex = 0; + private byte[] indices = new byte[NUMTESTS * NUMTESTS]; + boolean testdone = false; + + private synchronized void setShape(int index) { + shapeIndex = index; + testdone = false; + start(); + } + + public void run() { + Thread me = Thread.currentThread(); + Graphics2D g2d = (Graphics2D) getGraphics(); + byte[] indices; + Shape s = testShapes[shapeIndex]; + synchronized (this) { + if (renderer != me) { + return; + } + this.indices = new byte[NUMTESTS * NUMTESTS]; + java.util.Arrays.fill(this.indices, (byte) 8); + indices = this.indices; + } + + System.err.printf("%s %s\n", g2d, Color.yellow); + g2d.setColor(Color.yellow); + g2d.fillRect(0, 0, TESTSIZE, TESTSIZE); + int numtests = 0; + long start = System.currentTimeMillis(); + for (int y = 0; renderer == me && y < TESTSIZE; y += BOXSIZE) { + for (int x = 0; renderer == me && x < TESTSIZE; x += BOXSIZE) { + byte index = 0; + if (s.intersects(x, y, BOXSIZE, BOXSIZE)) { + index += 1; + } + if (s.contains(x + BOXCENTER, y + BOXCENTER)) { + index += 2; + } + if (s.contains(x, y, BOXSIZE, BOXSIZE)) { + index += 4; + } + numtests++; + int i = (y / BOXSIZE) * NUMTESTS + (x / BOXSIZE); + indices[i] = index; + g2d.setColor(colors[index]); + g2d.fillRect(x, y, BOXSIZE, BOXSIZE); + } + } + synchronized (this) { + if (renderer != me) { + return; + } + g2d.setColor(new Color(0, 0, 1, .2f)); + g2d.fill(s); + testdone = true; + long end = System.currentTimeMillis(); + System.out.println(numtests + " tests took " + (end - start) + "ms"); + } + } + + public void paint(Graphics g) { + g.setColor(Color.yellow); + g.fillRect(0, 0, TESTSIZE, TESTSIZE); + byte[] indices = this.indices; + if (indices != null) { + for (int y = 0; y < TESTSIZE; y += BOXSIZE) { + for (int x = 0; x < TESTSIZE; x += BOXSIZE) { + int i = (y / BOXSIZE) * NUMTESTS + (x / BOXSIZE); + g.setColor(colors[indices[i]]); + g.fillRect(x, y, BOXSIZE, BOXSIZE); + } + } + } + Graphics2D g2d = (Graphics2D) g; + g2d.setColor(new Color(0, 0, 1, .2f)); + g2d.fill(testShapes[shapeIndex]); + } + } + + static volatile PathHitTestManual pathHitTestManual; + + private static void createAndShowGUI() { + pathHitTestManual = new PathHitTestManual(); + Frame frame = new Frame("PathHitTestManual test window"); + + frame.add(pathHitTestManual); + frame.setSize(400, 450); + + PassFailJFrame.addTestWindow(frame); + PassFailJFrame.positionTestWindow(frame, PassFailJFrame.Position.HORIZONTAL); + + frame.setVisible(true); + + pathHitTestManual.init(); + pathHitTestManual.start(); + } + + public static void doManual() throws Exception { + PassFailJFrame passFailJFrame = new PassFailJFrame.Builder() + .title("PathHitTestManual Instructions") + .instructions(INSTRUCTIONS) + .testTimeOut(5) + .rows(30) + .columns(70) + .screenCapture() + .build(); + + EventQueue.invokeAndWait(PathHitTestManual::createAndShowGUI); + try { + passFailJFrame.awaitAndCheck(); + } finally { + pathHitTestManual.stop(); + } + } + } +}