Skip to content
Snippets Groups Projects
Commit 37c9cd15 authored by Goetz Lindenmaier's avatar Goetz Lindenmaier
Browse files

8283803: Remove jtreg tag manual=yesno for...

8283803: Remove jtreg tag manual=yesno for java/awt/print/PrinterJob/PrintGlyphVectorTest.java and fix test
8284898: Enhance PassFailJFrame

Reviewed-by: stuefe
Backport-of: ed23033dc6b3d4833ce2c8d07f273747ab8ae406
parent 6fa5281c
No related branches found
No related tags found
No related merge requests found
/*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2022, 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
......@@ -24,19 +24,46 @@
/*
* @test
* @bug 8029204
* @library ../../regtesthelpers
* @build PassFailJFrame
* @summary Tests GlyphVector is printed in the correct location
* @run main/manual=yesno PrintGlyphVectorTest
* @run main/manual PrintGlyphVectorTest
*/
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.font.*;
import java.awt.geom.*;
import java.awt.print.*;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Label;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
public class PrintGlyphVectorTest extends Component implements Printable {
private static final String INSTRUCTIONS = """
Note: You must have a printer installed for this test.
If printer is not available, the test passes automatically.
Press the PRINT button on the 'Test PrintGlyphVector' frame
and press OK/print button on the print dialog.
Retrieve the output and compare the printed and on-screen
text to confirm that in both cases the text is aligned and
the boxes are around the text, not offset from the text.
""";
public void drawGVs(Graphics g) {
String testString = "0123456789abcdefghijklm";
......@@ -46,9 +73,8 @@ public class PrintGlyphVectorTest extends Component implements Printable {
FontRenderContext frc = g2d.getFontRenderContext();
GlyphVector v = font.createGlyphVector(frc, testString);
float x = 50f,
y = 50f;
float x = 50f;
float y = 50f;
g2d.drawGlyphVector(v, x, y);
Rectangle2D r = v.getVisualBounds();
......@@ -69,9 +95,6 @@ public class PrintGlyphVectorTest extends Component implements Printable {
r = v.getVisualBounds();
r.setRect(r.getX()+x, r.getY()+y, r.getWidth(), r.getHeight());
g2d.draw(r);
}
public void paint(Graphics g) {
......@@ -97,54 +120,48 @@ public class PrintGlyphVectorTest extends Component implements Printable {
return Printable.PAGE_EXISTS;
}
private static void createTestUI() {
PrinterJob pj = PrinterJob.getPrinterJob();
if (pj.getPrintService() == null) {
System.out.println("Printer not configured or available."
+ " Test cannot continue.");
PassFailJFrame.forcePass();
}
public static void main(String arg[]) throws Exception {
Frame f = new Frame();
Frame f = new Frame("Test PrintGlyphVector");
PrintGlyphVectorTest pvt = new PrintGlyphVectorTest();
f.add("Center", pvt);
f.add("South", new PrintInstructions());
f.pack();
f.show();
f.add(pvt, BorderLayout.CENTER);
Button printButton = new Button("PRINT");
printButton.addActionListener((e) -> {
pj.setPrintable(new PrintGlyphVectorTest());
if (pj.printDialog()) {
try {
pj.print();
} catch (PrinterException ex) {
throw new RuntimeException(ex.getMessage());
}
} else {
throw new RuntimeException("Test failed : "
+ "User selected 'Cancel' button on the print dialog");
}
});
class PrintInstructions extends Panel implements ActionListener {
static final String INSTRUCTIONS =
"You must have a printer installed for this test.\n" +
"Press the PRINT button below and OK the print dialog\n" +
"Retrieve the output and compare the printed and on-screen text\n" +
" to confirm that in both cases the text is aligned and the boxes\n" +
"are around the text, not offset from the text.";
f.add(printButton, BorderLayout.SOUTH);
f.pack();
f.setVisible(true);
PrintInstructions() {
// add the test frame to dispose
PassFailJFrame.addTestFrame(f);
setLayout(new GridLayout(2,1));
TextArea t = new TextArea(INSTRUCTIONS, 8, 80);
add(t);
Button b = new Button("PRINT");
b.setFont(new Font("Dialog", Font.BOLD, 30));
b.addActionListener(this);
add(b);
// Arrange the test instruction frame and test frame side by side
PassFailJFrame.positionTestFrame(f, PassFailJFrame.Position.HORIZONTAL);
}
public void actionPerformed(ActionEvent e) {
PrinterJob pj = PrinterJob.getPrinterJob();
if (pj == null ||
pj.getPrintService() == null ||
!pj.printDialog()) {
return;
}
pj.setPrintable(new PrintGlyphVectorTest());
try {
pj.print();
} catch (PrinterException ex) {
System.err.println(ex);
public static void main(String[] arg) throws Exception {
PassFailJFrame passFailJFrame = new PassFailJFrame(INSTRUCTIONS);
createTestUI();
passFailJFrame.awaitAndCheck();
}
}
}
/*
* Copyright (c) 2022, 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.Dimension;
import java.awt.Frame;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
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;
public class PassFailJFrame {
private static final String TITLE = "Test Instruction Frame";
private static final long TEST_TIMEOUT = 5;
private static final int ROWS = 10;
private static final int COLUMNS = 40;
private static final List<Frame> frameList = new ArrayList<>();
private static final Timer timer = new Timer(0, null);
private static final CountDownLatch latch = new CountDownLatch(1);
private static volatile boolean failed;
private static volatile boolean timeout;
private static volatile String testFailedReason;
private static JFrame frame;
public enum Position {HORIZONTAL, VERTICAL}
public PassFailJFrame(String instructions) throws InterruptedException,
InvocationTargetException {
this(instructions, TEST_TIMEOUT);
}
public PassFailJFrame(String instructions, long testTimeOut) throws
InterruptedException, InvocationTargetException {
this(TITLE, instructions, testTimeOut);
}
public PassFailJFrame(String title, String instructions,
long testTimeOut) throws InterruptedException,
InvocationTargetException {
this(title, instructions, testTimeOut, ROWS, COLUMNS);
}
/**
* 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.
*
* @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
* @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) throws InterruptedException,
InvocationTargetException {
if (isEventDispatchThread()) {
createUI(title, instructions, testTimeOut, rows, columns);
} else {
invokeAndWait(() -> createUI(title, instructions, testTimeOut,
rows, columns));
}
}
private static void createUI(String title, String instructions,
long testTimeOut, int rows, int columns) {
frame = new JFrame(title);
frame.setLayout(new BorderLayout());
JTextArea instructionsText = new JTextArea(instructions, rows, columns);
instructionsText.setEditable(false);
instructionsText.setLineWrap(true);
long tTimeout = TimeUnit.MINUTES.toMillis(testTimeOut);
final JLabel testTimeoutLabel = new JLabel(String.format("Test " +
"timeout: %s", convertMillisToTimeStr(tTimeout)), JLabel.CENTER);
final long startTime = System.currentTimeMillis();
timer.setDelay(1000);
timer.addActionListener((e) -> {
long leftTime = tTimeout - (System.currentTimeMillis() - startTime);
if ((leftTime < 0) || failed) {
timer.stop();
testFailedReason = "Failure Reason:\n"
+ "Timeout User did not perform testing.";
timeout = true;
latch.countDown();
}
testTimeoutLabel.setText(String.format("Test timeout: %s", convertMillisToTimeStr(leftTime)));
});
timer.start();
frame.add(testTimeoutLabel, BorderLayout.NORTH);
frame.add(new JScrollPane(instructionsText), BorderLayout.CENTER);
JButton btnPass = new JButton("Pass");
btnPass.addActionListener((e) -> {
latch.countDown();
timer.stop();
});
JButton btnFail = new JButton("Fail");
btnFail.addActionListener((e) -> {
getFailureReason();
timer.stop();
});
JPanel buttonsPanel = new JPanel();
buttonsPanel.add(btnPass);
buttonsPanel.add(btnFail);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
testFailedReason = "Failure Reason:\n"
+ "User closed the instruction Frame";
failed = true;
latch.countDown();
}
});
frame.add(buttonsPanel, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frameList.add(frame);
}
private static String convertMillisToTimeStr(long millis) {
if (millis < 0) {
return "00:00:00";
}
long hours = millis / 3_600_000;
long minutes = (millis - hours * 3_600_000) / 60_000;
long seconds = (millis - hours * 3_600_000 - minutes * 60_000) / 1_000;
return String.format("%02d:%02d:%02d", hours, minutes, seconds);
}
/**
* Wait for the user decision i,e user selects pass or fail button.
* If user does not select pass or fail button then the test waits for
* the specified timeoutMinutes period and the test gets timeout.
* Note: This method should be called from main() thread
*
* @throws InterruptedException exception thrown when thread is
* interrupted
* @throws InvocationTargetException if an exception is thrown while
* disposing of frames on EDT
*/
public void awaitAndCheck() throws InterruptedException, InvocationTargetException {
if (isEventDispatchThread()) {
throw new IllegalStateException("awaitAndCheck() should not be called on EDT");
}
latch.await();
invokeAndWait(PassFailJFrame::disposeFrames);
if (timeout) {
throw new RuntimeException(testFailedReason);
}
if (failed) {
throw new RuntimeException("Test failed! : " + testFailedReason);
}
System.out.println("Test passed!");
}
/**
* Dispose all the frame(s) i,e both the test instruction frame as
* well as the frame that is added via addTestFrame(Frame frame)
*/
private static synchronized void disposeFrames() {
for (Frame f : frameList) {
f.dispose();
}
}
/**
* Read the test failure reason and add the reason to the test result
* example in the jtreg .jtr file.
*/
private static void getFailureReason() {
final JDialog dialog = new JDialog(frame, "Test Failure ", true);
dialog.setTitle("Failure reason");
JPanel jPanel = new JPanel(new BorderLayout());
JTextArea jTextArea = new JTextArea(5, 20);
JButton okButton = new JButton("OK");
okButton.addActionListener((ae) -> {
testFailedReason = "Failure Reason:\n" + jTextArea.getText();
dialog.setVisible(false);
});
jPanel.add(new JScrollPane(jTextArea), BorderLayout.CENTER);
JPanel okayBtnPanel = new JPanel();
okayBtnPanel.add(okButton);
jPanel.add(okayBtnPanel, BorderLayout.SOUTH);
dialog.add(jPanel);
dialog.setLocationRelativeTo(frame);
dialog.pack();
dialog.setVisible(true);
failed = true;
dialog.dispose();
latch.countDown();
}
/**
* Position the instruction frame with testFrame ( testcase created
* frame) by the specified position
* Note: This method should be invoked from the method that creates
* testFrame
*
* @param testFrame test frame that the test is created
* @param position position can be either HORIZONTAL (both test
* instruction frame and test frame as arranged side by
* side or VERTICAL ( both test instruction frame and
* test frame as arranged up and down)
*/
public static void positionTestFrame(Frame testFrame, Position position) {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
if (position.equals(Position.HORIZONTAL)) {
int newX = ((screenSize.width / 2) - frame.getWidth());
frame.setLocation(newX, frame.getY());
testFrame.setLocation((frame.getLocation().x + frame.getWidth() + 5), frame.getY());
} else if (position.equals(Position.VERTICAL)) {
int newY = ((screenSize.height / 2) - frame.getHeight());
frame.setLocation(frame.getX(), newY);
testFrame.setLocation(frame.getX(),
(frame.getLocation().y + frame.getHeight() + 5));
}
}
/**
* Add the testFrame to the frameList so that test instruction frame
* and testFrame and any other frame used in this test is disposed
* via disposeFrames()
*
* @param testFrame testFrame that needs to be disposed
*/
public static synchronized void addTestFrame(Frame testFrame) {
frameList.add(testFrame);
}
/**
* Forcibly pass the test.
* <p>The sample usage:
* <pre><code>
* PrinterJob pj = PrinterJob.getPrinterJob();
* if (pj == null || pj.getPrintService() == null) {
* System.out.println(""Printer not configured or available.");
* PassFailJFrame.forcePass();
* }
* </code></pre>
*/
public static void forcePass() {
latch.countDown();
}
/**
* Forcibly fail the test.
*/
public static void forceFail() {
failed = true;
latch.countDown();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment