Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.
/ jdk23u Public archive

Commit 167d346

Browse files
committed
8340785: Update description of PassFailJFrame and samples
Backport-of: 5063494
1 parent ff8ac15 commit 167d346

File tree

1 file changed

+159
-33
lines changed

1 file changed

+159
-33
lines changed

test/jdk/java/awt/regtesthelpers/PassFailJFrame.java

+159-33
Original file line numberDiff line numberDiff line change
@@ -79,23 +79,85 @@
7979
import static javax.swing.SwingUtilities.isEventDispatchThread;
8080

8181
/**
82-
* Provides a framework for manual tests to display test instructions and
83-
* Pass/Fail buttons.
82+
* A framework for manual tests to display test instructions and
83+
* <i>Pass</i> / <i>Fail</i> buttons. The framework automatically
84+
* creates a frame to display the instructions, provides buttons
85+
* to select the test result, and handles test timeout.
86+
*
87+
* <p id="timeOutTimer">
88+
* The instruction UI frame displays a timer at the top which indicates
89+
* how much time is left. The timer can be paused using the <i>Pause</i>
90+
* button to the right of the time; the title of the button changes to
91+
* <i>Resume</i>. To resume the timer, use the <i>Resume</i> button.
92+
*
93+
* <p id="instructionText">
94+
* In the center, the instruction UI frame displays instructions for the
95+
* tester. The instructions can be either plain text or HTML. If the
96+
* text of the instructions starts with {@code "<html>"}, the
97+
* instructions are displayed as HTML, as supported by Swing, which
98+
* provides richer formatting options.
99+
* <p>
100+
* The instructions are displayed in a text component with word-wrapping
101+
* so that there's no horizontal scroll bar. If the text doesn't fit, a
102+
* vertical scroll bar is shown. Use {@code rows} and {@code columns}
103+
* parameters to change the size of this text component.
104+
* If possible, choose the number of rows and columns so that
105+
* the instructions fit and no scroll bars are shown.
106+
*
107+
* <p id="passFailButtons">
108+
* At the bottom, the instruction UI frame displays the
109+
* <i>Pass</i> and <i>Fail</i> buttons. The tester clicks either <i>Pass</i>
110+
* or <i>Fail</i> button to finish the test. When the tester clicks the
111+
* <i>Fail</i> button, the framework displays a dialog box prompting for
112+
* a reason why the test fails. The tester enters the reason and clicks
113+
* <i>OK</i> to close the dialog and fail the test,
114+
* or simply closes the dialog to fail the test without providing any reason.
115+
*
116+
* <p id="screenCapture">
117+
* If you enable the screenshot feature, a <i>Screenshot</i> button is
118+
* added to the right of the <i>Fail</i> button. The tester can choose either
119+
* <i>Capture Full Screen</i> (default) or <i>Capture Frames</i> and click the
120+
* <i>Screenshot</i> button to take a screenshot.
121+
* If there are multiple screens, screenshots of each screen are created.
122+
* If the tester selects the <i>Capture Frames</i> mode, screenshots of all
123+
* the windows or frames registered in the {@code PassFailJFrame} framework
124+
* are created.
125+
*
126+
* <p id="logArea">
127+
* If you enable a log area, the instruction UI frame adds a text component
128+
* to display log messages below the buttons.
129+
* Use {@link #log(String) log}, {@link #logSet(String) logSet}
130+
* and {@link #logClear() logClear} static methods of {@code PassFailJFrame}
131+
* to add or clear messages from the log area.
132+
*
133+
* <p id="awaitTestResult">
134+
* After you create an instance of {@code PassFailJFrame}, call the
135+
* {@link #awaitAndCheck() awaitAndCheck} method to stop the current thread
136+
* (usually the main thread) and wait until the tester clicks
137+
* either <i>Pass</i> or <i>Fail</i> button,
138+
* or until the test times out.
84139
* <p>
85-
* Instructions for the user can be either plain text or HTML as supported
86-
* by Swing. If the instructions start with {@code <html>}, the
87-
* instructions are displayed as HTML.
140+
* The call to the {@code awaitAndCheck} method is usually the last
141+
* statement in the {@code main} method of your test.
142+
* If the test fails, an exception is thrown to signal the failure to jtreg.
143+
* The test fails if the tester clicks the <i>Fail</i> button,
144+
* if the timeout occurs,
145+
* or if any window or frame is closed.
88146
* <p>
147+
* Before returning from {@code awaitAndCheck}, the framework disposes of
148+
* all the windows and frames.
149+
*
150+
* <h2 id="sampleManualTest">Sample Manual Test</h2>
89151
* A simple test would look like this:
90-
* <pre>{@code
152+
* {@snippet id='sampleManualTestCode' lang='java':
91153
* public class SampleManualTest {
92154
* private static final String INSTRUCTIONS =
93155
* "Click Pass, or click Fail if the test failed.";
94156
*
95157
* public static void main(String[] args) throws Exception {
96158
* PassFailJFrame.builder()
97159
* .instructions(INSTRUCTIONS)
98-
* .testUI(() -> createTestUI())
160+
* .testUI(SampleManualTest::createTestUI)
99161
* .build()
100162
* .awaitAndCheck();
101163
* }
@@ -106,39 +168,87 @@
106168
* return testUI;
107169
* }
108170
* }
109-
* }</pre>
171+
* }
110172
* <p>
111-
* The above example uses the {@link Builder Builder} to set the parameters of
112-
* the instruction frame. It is the recommended way.
173+
* The above example uses the {@link Builder Builder} class to set
174+
* the parameters of the instruction frame.
175+
* It is <em>the recommended way</em>.
176+
*
113177
* <p>
114-
* The framework will create instruction UI, it will call
115-
* the provided {@code createTestUI} on the Event Dispatch Thread (EDT),
116-
* and it will automatically position the test UI and make it visible.
178+
* The framework will create an instruction UI frame, it will call
179+
* the provided {@code createTestUI} on the Event Dispatch Thread (<dfn>EDT</dfn>),
180+
* and it will automatically position the test UI frame and make it visible.
181+
*
182+
* <p id="jtregTagsForTest">
183+
* Add the following jtreg tags before the test class declaration
184+
* {@snippet :
185+
* /*
186+
* * @test
187+
* * @summary Sample manual test
188+
* * @library /java/awt/regtesthelpers
189+
* * @build PassFailJFrame
190+
* * @run main/manual SampleManualTest
191+
* }
192+
* and the closing comment tag <code>*&#47;</code>.
117193
* <p>
194+
* The {@code @library} tag points to the location of the
195+
* {@code PassFailJFrame} class in the source code;
196+
* the {@code @build} tag makes jtreg compile the {@code PassFailJFrame} class,
197+
* and finally the {@code @run} tag specifies it is a manual
198+
* test and the class to run.
199+
*
200+
* <h2 id="usingBuilder">Using {@code Builder}</h2>
201+
* Use methods of the {@link Builder Builder} class to set or change
202+
* parameters of {@code PassFailJFrame} and its instruction UI:
203+
* <ul>
204+
* <li>{@link Builder#title(String) title} sets
205+
* the title of the instruction UI
206+
* (the default is {@value #TITLE});</li>
207+
* <li>{@link Builder#testTimeOut(long) testTimeOut} sets
208+
* the timeout of the test
209+
* (the default is {@value #TEST_TIMEOUT});</li>
210+
* <li>{@link Builder#rows(int) rows} and
211+
* {@link Builder#columns(int) columns} control the size
212+
* the text component which displays the instructions
213+
* (the default number of rows is the number of lines in the text
214+
* of the instructions,
215+
* the default number of columns is {@value #COLUMNS});</li>
216+
* <li>{@link Builder#logArea() logArea} adds a log area;</li>
217+
* <li>{@link Builder#screenCapture() screenCapture}
218+
* enables screenshots.</li>
219+
* </ul>
220+
*
221+
* <h3 id="builderTestUI">Using {@code testUI} and {@code splitUI}</h3>
118222
* The {@code Builder.testUI} methods accept interfaces which create one window
119223
* or a list of windows if the test needs multiple windows,
120224
* or directly a single window, an array of windows or a list of windows.
121225
* <p>
122-
* For simple test UI, use {@code Builder.splitUI}, or explicitly
123-
* {@code Builder.splitUIRight} or {@code Builder.splitUIBottom} with
124-
* a {@code PanelCreator}. The framework will call the provided
125-
* {@code createUIPanel} to create the component with test UI and
226+
* For simple test UI, use {@link Builder#splitUI(PanelCreator) splitUI},
227+
* or explicitly
228+
* {@link Builder#splitUIRight(PanelCreator) splitUIRight} or
229+
* {@link Builder#splitUIBottom(PanelCreator) splitUIBottom} with
230+
* a {@link PanelCreator PanelCreator}.
231+
* The framework will call the provided
232+
* {@code createUIPanel} method to create the component with test UI and
126233
* will place it as the right or bottom component in a split pane
127234
* along with instruction UI.
128235
* <p>
236+
* Note: <em>support for multiple windows is incomplete</em>.
237+
*
238+
* <h2 id="obsoleteSampleTest">Obsolete Sample Test</h2>
129239
* Alternatively, use one of the {@code PassFailJFrame} constructors to
130240
* create an object, then create secondary test UI, register it
131241
* with {@code PassFailJFrame}, position it and make it visible.
132242
* The following sample demonstrates it:
133-
* <pre>{@code
134-
* public class SampleOldManualTest {
243+
* {@snippet id='obsoleteSampleTestCode' lang='java':
244+
* public class ObsoleteManualTest {
135245
* private static final String INSTRUCTIONS =
136246
* "Click Pass, or click Fail if the test failed.";
137247
*
138248
* public static void main(String[] args) throws Exception {
139249
* PassFailJFrame passFail = new PassFailJFrame(INSTRUCTIONS);
140250
*
141-
* SwingUtilities.invokeAndWait(() -> createTestUI());
251+
* SwingUtilities.invokeAndWait(ObsoleteManualTest::createTestUI);
142252
*
143253
* passFail.awaitAndCheck();
144254
* }
@@ -151,17 +261,29 @@
151261
* testUI.setVisible(true);
152262
* }
153263
* }
154-
* }</pre>
264+
* }
155265
* <p>
156-
* Use methods of the {@code Builder} class or constructors of the
157-
* {@code PassFailJFrame} class to control other parameters:
158-
* <ul>
159-
* <li>the title of the instruction UI,</li>
160-
* <li>the timeout of the test,</li>
161-
* <li>the size of the instruction UI via rows and columns, and</li>
162-
* <li>to add a log area,</li>
163-
* <li>to enable screenshots.</li>
164-
* </ul>
266+
* This sample uses {@link #PassFailJFrame(String) a constructor} of
267+
* {@code PassFailJFrame} to create its instance,
268+
* there are several overloads provided which allow changing other parameters.
269+
* <p>
270+
* When you use the constructors, you have to explicitly create
271+
* your test UI window on EDT. After you create the window,
272+
* you need to register it with the framework using
273+
* {@link #addTestWindow(Window) addTestWindow}
274+
* to ensure the window is disposed of when the test completes.
275+
* Before showing the window, you have to call
276+
* {@link #positionTestWindow(Window, Position) positionTestWindow}
277+
* to position the test window near the instruction UI frame provided
278+
* by the framework. And finally you have to explicitly show the test UI
279+
* window by calling {@code setVisible(true)}.
280+
* <p>
281+
* To avoid the complexity, use the {@link Builder Builder} class
282+
* which provides a streamlined way to configure and create an
283+
* instance of {@code PassFailJFrame}.
284+
* <p>
285+
* Consider updating tests which use {@code PassFailJFrame} constructors to
286+
* use the builder pattern.
165287
*/
166288
public final class PassFailJFrame {
167289

@@ -541,7 +663,11 @@ private static JComponent createInstructionUIPanel(String instructions,
541663
: configurePlainText(instructions, rows, columns);
542664
text.setEditable(false);
543665

544-
main.add(new JScrollPane(text), BorderLayout.CENTER);
666+
JPanel textPanel = new JPanel(new BorderLayout());
667+
textPanel.setBorder(createEmptyBorder(4, 0, 0, 0));
668+
textPanel.add(new JScrollPane(text), BorderLayout.CENTER);
669+
670+
main.add(textPanel, BorderLayout.CENTER);
545671

546672
JButton btnPass = new JButton("Pass");
547673
btnPass.addActionListener((e) -> {
@@ -822,7 +948,7 @@ public void windowClosing(WindowEvent e) {
822948
private static JComponent createCapturePanel() {
823949
JComboBox<CaptureType> screenShortType = new JComboBox<>(CaptureType.values());
824950

825-
JButton capture = new JButton("ScreenShot");
951+
JButton capture = new JButton("Screenshot");
826952
capture.addActionListener((e) ->
827953
captureScreen((CaptureType) screenShortType.getSelectedItem()));
828954

@@ -834,7 +960,7 @@ private static JComponent createCapturePanel() {
834960

835961
private enum CaptureType {
836962
FULL_SCREEN("Capture Full Screen"),
837-
WINDOWS("Capture Individual Frame");
963+
WINDOWS("Capture Frames");
838964

839965
private final String type;
840966
CaptureType(String type) {

0 commit comments

Comments
 (0)