1 /* 2 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* @test 25 @bug 8211055 26 @summary Verifies "print to file" works even when there is no printer 27 @requires (os.family == "mac") 28 @run main/manual TestSaveFileWithoutPrinter 29 */ 30 31 import java.awt.BorderLayout; 32 import java.awt.FlowLayout; 33 import java.awt.Graphics; 34 import java.awt.event.WindowAdapter; 35 import java.awt.event.WindowEvent; 36 import java.awt.print.Printable; 37 import java.awt.print.PageFormat; 38 import java.awt.print.PrinterException; 39 import java.awt.print.PrinterJob; 40 import java.util.concurrent.CountDownLatch; 41 import java.util.concurrent.TimeUnit; 42 import javax.swing.JButton; 43 import javax.swing.JDialog; 44 import javax.swing.JLabel; 45 import javax.swing.JPanel; 46 import javax.swing.JTextArea; 47 import javax.swing.SwingUtilities; 48 import javax.swing.Timer; 49 import javax.swing.WindowConstants; 50 51 public class TestSaveFileWithoutPrinter implements Printable { 52 private static final CountDownLatch testEndedSignal = new CountDownLatch(1); 53 private static final int testTimeout = 300000; 54 private static volatile String testFailureMsg; 55 private static volatile boolean testPassed; 56 private static volatile boolean testFinished; 57 private static PrinterJob job; 58 main(String[] args)59 public static void main(String[] args) { 60 job = PrinterJob.getPrinterJob(); 61 if (job.getPrintService() != null) { 62 System.out.println("This test requires no printers to be installed. Exiting."); 63 return; 64 } 65 SwingUtilities.invokeLater(() -> createAndShowTestDialog()); 66 67 try { 68 if (!testEndedSignal.await(testTimeout, TimeUnit.MILLISECONDS)) { 69 throw new RuntimeException(String.format( 70 "Test timeout '%d ms' elapsed.", testTimeout)); 71 } 72 if (!testPassed) { 73 String failureMsg = testFailureMsg; 74 if ((failureMsg != null) && (!failureMsg.trim().isEmpty())) { 75 throw new RuntimeException(failureMsg); 76 } else { 77 throw new RuntimeException("Test failed."); 78 } 79 } 80 } catch (InterruptedException ie) { 81 throw new RuntimeException(ie); 82 } finally { 83 testFinished = true; 84 } 85 } 86 doTest()87 private static void doTest() { 88 job.setPrintable(new TestSaveFileWithoutPrinter()); 89 if (job.printDialog()) { 90 try { 91 job.print(); 92 } catch (PrinterException pe) { 93 throw new RuntimeException(pe); 94 } 95 } 96 } 97 pass()98 private static void pass() { 99 testPassed = true; 100 testEndedSignal.countDown(); 101 } 102 fail(String failureMsg)103 private static void fail(String failureMsg) { 104 testFailureMsg = failureMsg; 105 testPassed = false; 106 testEndedSignal.countDown(); 107 } 108 convertMillisToTimeStr(int millis)109 private static String convertMillisToTimeStr(int millis) { 110 if (millis < 0) { 111 return "00:00:00"; 112 } 113 int hours = millis / 3600000; 114 int minutes = (millis - hours * 3600000) / 60000; 115 int seconds = (millis - hours * 3600000 - minutes * 60000) / 1000; 116 return String.format("%02d:%02d:%02d", hours, minutes, seconds); 117 } 118 createAndShowTestDialog()119 private static void createAndShowTestDialog() { 120 String description = 121 " To run this test it is required to delete any installed printers.\r\n" + 122 "\r\n" + 123 " 1. Verify that saving file via \"Save as PDF\" results in saving file\r\n" + 124 " even if there is no installed printer.\r\n" + 125 " 2. Click on \"Start Test\" button.\r\n" + 126 " 3. In the shown print dialog select \"Save as PDF\" in PDF drop-down list\r\n" + 127 " 4. Another dialog opens prompting for filename, enter any filename and press \"Save\".\r\n" + 128 "\r\n" + 129 " If the file is saved without any PrinterException, click on \"PASS\"\r\n" + 130 " button, otherwise click on \"FAIL\" button."; 131 132 final JDialog dialog = new JDialog(); 133 dialog.setTitle("SaveFileWithoutPrinter"); 134 dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 135 dialog.addWindowListener(new WindowAdapter() { 136 @Override 137 public void windowClosing(WindowEvent e) { 138 dialog.dispose(); 139 fail("Main dialog was closed."); 140 } 141 }); 142 143 final JLabel testTimeoutLabel = new JLabel(String.format( 144 "Test timeout: %s", convertMillisToTimeStr(testTimeout))); 145 final long startTime = System.currentTimeMillis(); 146 final Timer timer = new Timer(0, null); 147 timer.setDelay(1000); 148 timer.addActionListener((e) -> { 149 int leftTime = testTimeout - (int) (System.currentTimeMillis() - startTime); 150 if ((leftTime < 0) || testFinished) { 151 timer.stop(); 152 dialog.dispose(); 153 } 154 testTimeoutLabel.setText(String.format( 155 "Test timeout: %s", convertMillisToTimeStr(leftTime))); 156 }); 157 timer.start(); 158 159 JTextArea textArea = new JTextArea(description); 160 textArea.setEditable(false); 161 162 final JButton testButton = new JButton("Start Test"); 163 final JButton passButton = new JButton("PASS"); 164 final JButton failButton = new JButton("FAIL"); 165 testButton.addActionListener((e) -> { 166 testButton.setEnabled(false); 167 new Thread(() -> { 168 try { 169 doTest(); 170 171 SwingUtilities.invokeLater(() -> { 172 passButton.setEnabled(true); 173 failButton.setEnabled(true); 174 }); 175 } catch (Throwable t) { 176 t.printStackTrace(); 177 dialog.dispose(); 178 fail("Exception occurred in a thread executing the test."); 179 } 180 }).start(); 181 }); 182 passButton.setEnabled(false); 183 passButton.addActionListener((e) -> { 184 dialog.dispose(); 185 pass(); 186 }); 187 failButton.setEnabled(false); 188 failButton.addActionListener((e) -> { 189 dialog.dispose(); 190 fail("PrinterException thrown."); 191 }); 192 193 JPanel mainPanel = new JPanel(new BorderLayout()); 194 JPanel labelPanel = new JPanel(new FlowLayout()); 195 labelPanel.add(testTimeoutLabel); 196 mainPanel.add(labelPanel, BorderLayout.NORTH); 197 mainPanel.add(textArea, BorderLayout.CENTER); 198 JPanel buttonPanel = new JPanel(new FlowLayout()); 199 buttonPanel.add(testButton); 200 buttonPanel.add(passButton); 201 buttonPanel.add(failButton); 202 mainPanel.add(buttonPanel, BorderLayout.SOUTH); 203 dialog.add(mainPanel); 204 205 dialog.pack(); 206 dialog.setVisible(true); 207 } 208 209 @Override print(Graphics g, PageFormat pf, int pageIndex)210 public int print(Graphics g, PageFormat pf, int pageIndex) 211 throws PrinterException { 212 if (pageIndex == 0) { 213 return Printable.PAGE_EXISTS; 214 } else { 215 return Printable.NO_SUCH_PAGE; 216 } 217 } 218 } 219