diff --git a/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java b/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java index a13d6ee2e08..92ff9371933 100644 --- a/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java +++ b/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 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 @@ -21,31 +21,44 @@ * questions. */ +import java.awt.AWTException; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; +import java.awt.Image; import java.awt.Insets; import java.awt.Rectangle; +import java.awt.Robot; import java.awt.Toolkit; import java.awt.Window; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.awt.image.RenderedImage; +import java.io.File; +import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import javax.imageio.ImageIO; import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; +import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.Timer; - import static javax.swing.SwingUtilities.invokeAndWait; import static javax.swing.SwingUtilities.isEventDispatchThread; @@ -68,7 +81,9 @@ public class PassFailJFrame { private static volatile boolean failed; private static volatile boolean timeout; private static volatile String testFailedReason; + private static final AtomicInteger imgCounter = new AtomicInteger(0); private static JFrame frame; + private static Robot robot; public enum Position {HORIZONTAL, VERTICAL, TOP_LEFT_CORNER} @@ -114,16 +129,62 @@ public class PassFailJFrame { public PassFailJFrame(String title, String instructions, long testTimeOut, int rows, int columns) throws InterruptedException, InvocationTargetException { + this(title, instructions, testTimeOut, rows, columns, false); + } + + /** + * Constructs a JFrame with a given title & serves as test instructional + * frame where the user follows the specified test instruction in order + * to test the test case & mark the test pass or fail. If the expected + * result is seen then the user click on the 'Pass' button else click + * on the 'Fail' button and the reason for the failure should be + * specified in the JDialog JTextArea. + *
+ * The test instruction frame also provides a way for the tester to take
+ * a screenshot (full screen or individual frame) if this feature
+ * is enabled by passing {@code true} as {@code enableScreenCapture}
+ * parameter.
+ *
+ * @param title title of the Frame.
+ * @param instructions the instruction for the tester on how to test
+ * and what is expected (pass) and what is not
+ * expected (fail).
+ * @param testTimeOut test timeout where time is specified in minutes.
+ * @param rows number of visible rows of the JTextArea where the
+ * instruction is show.
+ * @param columns Number of columns of the instructional
+ * JTextArea
+ * @param enableScreenCapture if set to true, 'Capture Screen' button & its
+ * associated UIs are added to test instruction
+ * frame
+ * @throws InterruptedException exception thrown when thread is
+ * interrupted
+ * @throws InvocationTargetException if an exception is thrown while
+ * creating the test instruction frame on
+ * EDT
+ */
+ public PassFailJFrame(String title, String instructions, long testTimeOut,
+ int rows, int columns,
+ boolean enableScreenCapture) throws InterruptedException,
+ InvocationTargetException {
if (isEventDispatchThread()) {
- createUI(title, instructions, testTimeOut, rows, columns);
+ createUI(title, instructions, testTimeOut, rows, columns,
+ enableScreenCapture);
} else {
invokeAndWait(() -> createUI(title, instructions, testTimeOut,
- rows, columns));
+ rows, columns, enableScreenCapture));
}
}
+ private PassFailJFrame(Builder builder) throws InterruptedException,
+ InvocationTargetException {
+ this(builder.title, builder.instructions, builder.testTimeOut,
+ builder.rows, builder.columns, builder.screenCapture);
+ }
+
private static void createUI(String title, String instructions,
- long testTimeOut, int rows, int columns) {
+ long testTimeOut, int rows, int columns,
+ boolean enableScreenCapture) {
frame = new JFrame(title);
frame.setLayout(new BorderLayout());
JTextArea instructionsText = new JTextArea(instructions, rows, columns);
@@ -167,6 +228,10 @@ public class PassFailJFrame {
buttonsPanel.add(btnPass);
buttonsPanel.add(btnFail);
+ if (enableScreenCapture) {
+ buttonsPanel.add(createCapturePanel());
+ }
+
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
@@ -184,6 +249,91 @@ public class PassFailJFrame {
windowList.add(frame);
}
+ private static JComponent createCapturePanel() {
+ JComboBox