1 /*
   2  * Copyright (c) 2014, 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 import java.awt.BorderLayout;
  24 import java.awt.Color;
  25 import java.awt.Dialog;
  26 import java.awt.FlowLayout;
  27 import java.awt.print.Printable;
  28 import java.awt.print.PrinterException;
  29 import java.awt.print.PrinterJob;
  30 import java.text.MessageFormat;
  31 import javax.print.attribute.HashPrintRequestAttributeSet;
  32 import javax.print.attribute.PrintRequestAttributeSet;
  33 import javax.print.attribute.standard.Copies;
  34 import javax.print.attribute.standard.DialogTypeSelection;
  35 import javax.print.attribute.standard.MediaPrintableArea;
  36 import javax.swing.JButton;
  37 import javax.swing.JDialog;
  38 import javax.swing.JFrame;
  39 import javax.swing.JPanel;
  40 import javax.swing.JTable;
  41 import javax.swing.JTextArea;
  42 import javax.swing.SwingUtilities;
  43 import javax.swing.table.AbstractTableModel;
  44 import javax.swing.table.TableModel;
  45 
  46 /**
  47  * @test
  48  * @bug 8044444
  49  * @summary The output's 'Page-n' footer does not show completely
  50  * @author Alexandr Scherbatiy
  51  * @run main/manual ImageableAreaTest
  52  */
  53 public class ImageableAreaTest {
  54 
  55     public static void main(String[] args) throws Exception {
  56         SwingUtilities.invokeAndWait(new Runnable() {
  57 
  58             @Override
  59             public void run() {
  60 
  61                 createAndShowTestDialog(
  62                         "1. Press the Print Table button\n"
  63                         + " Java print dialog should appear.\n"
  64                         + "2. Press the Print button on the Java Print dialog.\n"
  65                         + "2. Check that the page number is correctly printed.\n"
  66                         + "If so, press PASS, else press FAIL.",
  67                         "Page number is not correctly printed!",
  68                         ImageableAreaTest::printWithJavaPrintDialog);
  69 
  70                 createAndShowTestDialog(
  71                         "1. Press the Print Table button\n"
  72                         + " The table should be printed without the print dialog.\n"
  73                         + "2. Check that the page number is correctly printed.\n"
  74                         + "If so, press PASS, else press FAIL.",
  75                         "Page number is not correctly printed!",
  76                         ImageableAreaTest::printWithoutPrintDialog);
  77 
  78                 createAndShowTestDialog(
  79                         "1. Press the Print Table button\n"
  80                         + " Java print dialog should appear.\n"
  81                         + "2. Press the Print button on the Java Print dialog.\n"
  82                         + "3. Check that the table has about half size of the printed page\n"
  83                         + "If so, press PASS, else press FAIL.",
  84                         "Custom imageable area is not correctly printed!",
  85                         ImageableAreaTest::printWithCustomImageareaSize);
  86             }
  87         });
  88     }
  89 
  90     private static void printWithJavaPrintDialog() {
  91         final JTable table = createAuthorTable(42);
  92         Printable printable = table.getPrintable(
  93                 JTable.PrintMode.NORMAL,
  94                 new MessageFormat("Author Table"),
  95                 new MessageFormat("Page - {0}"));
  96 
  97         PrinterJob job = PrinterJob.getPrinterJob();
  98         job.setPrintable(printable);
  99 
 100         boolean printAccepted = job.printDialog();
 101         if (printAccepted) {
 102             try {
 103                 job.print();
 104                 closeFrame();
 105             } catch (PrinterException e) {
 106                 throw new RuntimeException(e);
 107             }
 108         }
 109     }
 110 
 111     private static void printWithoutPrintDialog() {
 112 
 113         final JTable table = createAuthorTable(42);
 114         PrintRequestAttributeSet pras
 115                 = new HashPrintRequestAttributeSet();
 116         pras.add(new Copies(1));
 117 
 118         try {
 119 
 120             boolean printAccepted = table.print(JTable.PrintMode.FIT_WIDTH,
 121                     new MessageFormat("Author Table"),
 122                     new MessageFormat("Page - {0}"),
 123                     false, pras, false);
 124 
 125             closeFrame();
 126             if (!printAccepted) {
 127                 throw new RuntimeException("User cancels the printer job!");
 128             }
 129 
 130         } catch (Exception e) {
 131             throw new RuntimeException(e);
 132         }
 133     }
 134 
 135     private static void printWithCustomImageareaSize() {
 136         final JTable table = createAuthorTable(18);
 137         PrintRequestAttributeSet printAttributes = new HashPrintRequestAttributeSet();
 138         printAttributes.add(DialogTypeSelection.NATIVE);
 139         printAttributes.add(new Copies(1));
 140         printAttributes.add(new MediaPrintableArea(
 141                 0.25f, 0.25f, 8.0f, 5.0f, MediaPrintableArea.INCH));
 142         Printable printable = table.getPrintable(
 143                 JTable.PrintMode.NORMAL,
 144                 new MessageFormat("Author Table"),
 145                 new MessageFormat("Page - {0}")
 146         );
 147 
 148         PrinterJob job = PrinterJob.getPrinterJob();
 149         job.setPrintable(printable);
 150 
 151         boolean printAccepted = job.printDialog(printAttributes);
 152         if (printAccepted) {
 153             try {
 154                 job.print();
 155                 closeFrame();
 156             } catch (Exception e) {
 157                 throw new RuntimeException(e);
 158             }
 159         } else {
 160             throw new RuntimeException("User cancels the printer job!");
 161         }
 162     }
 163 
 164     private static JFrame frame;
 165 
 166     private static void closeFrame() {
 167         if (frame != null) {
 168             frame.setVisible(false);
 169             frame.dispose();
 170         }
 171     }
 172 
 173     private static JTable createAuthorTable(int rows) {
 174         final String[] headers = {"Book", "Title"};
 175 
 176         final Object[][] data = new Object[rows][2];
 177         for (int i = 0; i < rows; i++) {
 178             int n = i + 1;
 179             data[i] = new Object[]{"Book: " + n, "Title: " + n};
 180         }
 181 
 182         TableModel dataModel = new AbstractTableModel() {
 183 
 184             public int getColumnCount() {
 185                 return headers.length;
 186             }
 187 
 188             public int getRowCount() {
 189                 return data.length;
 190             }
 191 
 192             public Object getValueAt(int row, int col) {
 193                 return data[row][col];
 194             }
 195 
 196             public String getColumnName(int column) {
 197                 return headers[column];
 198             }
 199 
 200             public Class getColumnClass(int col) {
 201                 return getValueAt(0, col).getClass();
 202             }
 203 
 204             public void setValueAt(Object aValue, int row, int column) {
 205                 data[row][column] = aValue;
 206             }
 207 
 208             public boolean isCellEditable(int row, int col) {
 209                 return false;
 210             }
 211         };
 212 
 213         JTable table = new JTable(dataModel);
 214         table.setGridColor(Color.BLUE);
 215         table.setBackground(Color.WHITE);
 216         table.setForeground(Color.BLACK);
 217         table.setSize(600, 800);
 218 
 219         frame = new JFrame();
 220         frame.setSize(400, 600);
 221         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 222         frame.add(table);
 223         frame.setVisible(true);
 224         return table;
 225     }
 226 
 227     private static int testCount;
 228 
 229     private static void createAndShowTestDialog(String description,
 230             String failMessage, Runnable action) {
 231         final JDialog dialog = new JDialog();
 232         dialog.setTitle("Test: " + (++testCount));
 233         dialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
 234         JTextArea textArea = new JTextArea(description);
 235         textArea.setEditable(false);
 236         final JButton testButton = new JButton("Print Table");
 237         final JButton passButton = new JButton("PASS");
 238         passButton.setEnabled(false);
 239         passButton.addActionListener((e) -> {
 240             dialog.dispose();
 241         });
 242         final JButton failButton = new JButton("FAIL");
 243         failButton.setEnabled(false);
 244         failButton.addActionListener((e) -> {
 245             throw new RuntimeException(failMessage);
 246         });
 247         testButton.addActionListener((e) -> {
 248             testButton.setEnabled(false);
 249             action.run();
 250             passButton.setEnabled(true);
 251             failButton.setEnabled(true);
 252         });
 253         JPanel mainPanel = new JPanel(new BorderLayout());
 254         mainPanel.add(textArea, BorderLayout.CENTER);
 255         JPanel buttonPanel = new JPanel(new FlowLayout());
 256         buttonPanel.add(testButton);
 257         buttonPanel.add(passButton);
 258         buttonPanel.add(failButton);
 259         mainPanel.add(buttonPanel, BorderLayout.SOUTH);
 260         dialog.add(mainPanel);
 261         dialog.pack();
 262         dialog.setVisible(true);
 263     }
 264 }