8328242: Add a log area to the PassFailJFrame

Reviewed-by: prr, aivanov, honkar
This commit is contained in:
Alexander Zvegintsev 2024-03-15 17:54:56 +00:00
parent 65a84c2642
commit 9bc1b065db

View File

@ -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;
* <li>the title of the instruction UI,</li>
* <li>the timeout of the test,</li>
* <li>the size of the instruction UI via rows and columns, and</li>
* <li>to add a log area</li>,
* <li>to enable screenshots.</li>
* </ul>
*/
@ -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.
* <p>
* 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.
* <p>
* The log area can be controlled by {@link #log(String)},
* {@link #logClear()} and {@link #logSet(String)}.
* <p>
* 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.