diff --git a/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java b/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java
index 55a219564a3..fcc45478d72 100644
--- a/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java
+++ b/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java
@@ -54,6 +54,7 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import javax.imageio.ImageIO;
+import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
@@ -156,6 +157,7 @@ import static javax.swing.SwingUtilities.isEventDispatchThread;
*
the title of the instruction UI,
* the timeout of the test,
* the size of the instruction UI via rows and columns, and
+ * to add a log area,
* to enable screenshots.
*
*/
@@ -205,6 +207,8 @@ public final class PassFailJFrame {
private static Robot robot;
+ private static JTextArea logArea;
+
public enum Position {HORIZONTAL, VERTICAL, TOP_LEFT_CORNER}
public PassFailJFrame(String instructions) throws InterruptedException,
@@ -374,6 +378,20 @@ public final class PassFailJFrame {
}
}
+ /**
+ * Does the same as {@link #invokeOnEDT(Runnable)}, but does not throw
+ * any checked exceptions.
+ *
+ * @param doRun an operation to run on EDT
+ */
+ private static void invokeOnEDTUncheckedException(Runnable doRun) {
+ try {
+ invokeOnEDT(doRun);
+ } catch (InterruptedException | InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
private static void createUI(String title, String instructions,
long testTimeOut, int rows, int columns,
boolean enableScreenCapture) {
@@ -385,7 +403,8 @@ public final class PassFailJFrame {
frame.add(createInstructionUIPanel(instructions,
testTimeOut,
rows, columns,
- enableScreenCapture),
+ enableScreenCapture,
+ false, 0),
BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
@@ -402,8 +421,9 @@ public final class PassFailJFrame {
createInstructionUIPanel(builder.instructions,
builder.testTimeOut,
builder.rows, builder.columns,
- builder.screenCapture);
-
+ builder.screenCapture,
+ builder.addLogArea,
+ builder.logAreaRows);
if (builder.splitUI) {
JSplitPane splitPane = new JSplitPane(
builder.splitUIOrientation,
@@ -422,7 +442,9 @@ public final class PassFailJFrame {
private static JComponent createInstructionUIPanel(String instructions,
long testTimeOut,
int rows, int columns,
- boolean enableScreenCapture) {
+ boolean enableScreenCapture,
+ boolean addLogArea,
+ int logAreaRows) {
JPanel main = new JPanel(new BorderLayout());
JLabel testTimeoutLabel = new JLabel("", JLabel.CENTER);
@@ -456,7 +478,20 @@ public final class PassFailJFrame {
buttonsPanel.add(createCapturePanel());
}
- main.add(buttonsPanel, BorderLayout.SOUTH);
+ if (addLogArea) {
+ logArea = new JTextArea(logAreaRows, columns);
+ logArea.setEditable(false);
+
+ Box buttonsLogPanel = Box.createVerticalBox();
+
+ buttonsLogPanel.add(buttonsPanel);
+ buttonsLogPanel.add(new JScrollPane(logArea));
+
+ main.add(buttonsLogPanel, BorderLayout.SOUTH);
+ } else {
+ main.add(buttonsPanel, BorderLayout.SOUTH);
+ }
+
main.setMinimumSize(main.getPreferredSize());
return main;
@@ -1041,6 +1076,36 @@ public final class PassFailJFrame {
latch.countDown();
}
+ /**
+ * Adds a {@code message} to the log area, if enabled by
+ * {@link Builder#logArea()} or {@link Builder#logArea(int)}.
+ *
+ * @param message to log
+ */
+ public static void log(String message) {
+ System.out.println("PassFailJFrame: " + message);
+ invokeOnEDTUncheckedException(() -> logArea.append(message + "\n"));
+ }
+
+ /**
+ * Clears the log area, if enabled by
+ * {@link Builder#logArea()} or {@link Builder#logArea(int)}.
+ */
+ public static void logClear() {
+ System.out.println("\nPassFailJFrame: log cleared\n");
+ invokeOnEDTUncheckedException(() -> logArea.setText(""));
+ }
+
+ /**
+ * Replaces the log area content with provided {@code text}, if enabled by
+ * {@link Builder#logArea()} or {@link Builder#logArea(int)}.
+ * @param text new text for the log area
+ */
+ public static void logSet(String text) {
+ System.out.println("\nPassFailJFrame: log set to:\n" + text + "\n");
+ invokeOnEDTUncheckedException(() -> logArea.setText(text));
+ }
+
public static final class Builder {
private String title;
private String instructions;
@@ -1048,6 +1113,8 @@ public final class PassFailJFrame {
private int rows;
private int columns;
private boolean screenCapture;
+ private boolean addLogArea;
+ private int logAreaRows = 10;
private List extends Window> testWindows;
private WindowListCreator windowListCreator;
@@ -1097,6 +1164,37 @@ public final class PassFailJFrame {
return this;
}
+ /**
+ * Adds a log area below the "Pass", "Fail" buttons.
+ *
+ * The log area can be controlled by {@link #log(String)},
+ * {@link #logClear()} and {@link #logSet(String)}.
+ *
+ * @return this builder
+ */
+ public Builder logArea() {
+ this.addLogArea = true;
+ return this;
+ }
+
+ /**
+ * Adds a log area below the "Pass", "Fail" buttons.
+ *
+ * The log area can be controlled by {@link #log(String)},
+ * {@link #logClear()} and {@link #logSet(String)}.
+ *
+ * The number of columns is taken from the number of
+ * columns in the instructional JTextArea.
+ *
+ * @param rows of the log area
+ * @return this builder
+ */
+ public Builder logArea(int rows) {
+ this.addLogArea = true;
+ this.logAreaRows = rows;
+ return this;
+ }
+
/**
* Adds a {@code WindowCreator} which the framework will use
* to create the test UI window.