Coverage Report - us.daveread.utility.formatcheck.print.Print
 
Classes in this File Line Coverage Branch Coverage Complexity
Print
0%
0/86
0%
0/14
1.8
 
 1  
 package us.daveread.utility.formatcheck.print;
 2  
 
 3  
 import java.io.*;
 4  
 import javax.print.attribute.*;
 5  
 import javax.print.attribute.standard.*;
 6  
 import java.util.*;
 7  
 import java.awt.*;
 8  
 import java.awt.print.*;
 9  
 import us.daveread.utility.formatcheck.ConstantsInterface;
 10  
 import us.daveread.utility.formatcheck.gui.Utils;
 11  
 import org.apache.log4j.Logger;
 12  
 
 13  
 /**
 14  
  * <p>Title: Print
 15  
  * <p>Description: Provide basic printing capability
 16  
  * <p>Copyright: Copyright (c) 2005
 17  
  * <p>This program is free software; you can redistribute it and/or modify
 18  
  * it under the terms of the GNU General Public License as published by
 19  
  * the Free Software Foundation; either version 2 of the License, or
 20  
  * (at your option) any later version.
 21  
  * <p>This program is distributed in the hope that it will be useful,
 22  
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 23  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 24  
  * GNU General Public License for more details.
 25  
  * <p>You should have received a copy of the GNU General Public License
 26  
  * along with this program; if not, write to the Free Software
 27  
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 28  
  * </p>
 29  
  *
 30  
  * @author David Read
 31  
  * @version $Id: Print.java,v 1.3 2006/06/14 23:35:18 daveread Exp $
 32  
  */
 33  
 public class Print implements Printable, Pageable {
 34  
 
 35  
     /** Number of lines to place on a page with variable font*/
 36  
     private final static int PAGELINESVARIABLEFONT = 55;
 37  
 
 38  
     /** Number of lines to place on a page with fixed font*/
 39  
     private final static int PAGELINESFIXEDFONT = 50;
 40  
 
 41  
     /** Number of columns per line for variable font */
 42  
     private final static int PAGECHARSPERLINEVARIABLEFONT = 90;
 43  
 
 44  
     /** Number of columns per line for variable font */
 45  
     private final static int PAGECHARSPERLINEFIXEDFONT = 76;
 46  
 
 47  
     /** Variability in line ending position for variable font */
 48  
     private final static int PAGECHARSVARIABILITYVARIABLEFONT = 20;
 49  
 
 50  
     /** Variability in line ending position for fixed font */
 51  
     private final static int PAGECHARSVARIABILITYFIXEDFONT = 10;
 52  
 
 53  
     /** Variable width font to use for output */
 54  0
     private final static Font fontVariable = new Font("Arial", Font.PLAIN, 9);
 55  
 
 56  
     /** Fixed width font to use for output */
 57  0
     private final static Font fontFixed = new Font("Courier", Font.PLAIN, 9);
 58  
 
 59  
     /** The title for the top of each page using this Print instance */
 60  
     private String title;
 61  
 
 62  
     /** The font to use for this Print instance */
 63  
     private Font font;
 64  
 
 65  
     /** The number of lines per page for this Print instance */
 66  
     private int pageLines;
 67  
 
 68  
     /** The number of characters per line for this Print instance */
 69  
     private int pageCharsPerLine;
 70  
 
 71  
     /** The number of characters a line can go beyond the chars limit before a
 72  
      * break is forced */
 73  
     private int pageCharsVariability;
 74  
 
 75  
     /** Parsed text to display */
 76  
     private String[] info;
 77  
 
 78  
     /** Number of pages required to print all the text */
 79  
     private int numPages;
 80  
 
 81  
     /** Logger */
 82  0
     private static final Logger logger = Logger.getLogger(Print.class);
 83  
 
 84  
     /**
 85  
      * Create a print instance.
 86  
      */
 87  
     public Print() {
 88  0
         this("Format Check Tool");
 89  0
     }
 90  
 
 91  
     /**
 92  
      * Create a print instance with the supplied title for each page.
 93  
      */
 94  0
     public Print(String aTitle) {
 95  0
         setTitle(aTitle);
 96  0
     }
 97  
 
 98  
     /**
 99  
      * Set the title for the top of each page.
 100  
      *
 101  
      * @param aTitle String The title to display at the top of each page
 102  
      */
 103  
     public void setTitle(String aTitle) {
 104  0
         if (aTitle != null) {
 105  0
             title = aTitle;
 106  
         }
 107  0
     }
 108  
 
 109  
     /**
 110  
      * Get the title set for this Print instance.
 111  
      *
 112  
      * @return String The current title
 113  
      */
 114  
     public String getTitle() {
 115  0
         return title;
 116  
     }
 117  
 
 118  
     /**
 119  
      * Print a string.  The string will be reformatted (line breaks added) as
 120  
      * necessary to reduce the odds of text being clipped on the right side of
 121  
      * the page.  A variable width font will be used.
 122  
      *
 123  
      * @param aToPrint String The string to be printed.
 124  
      */
 125  
     public void print(String aToPrint) {
 126  0
         print(aToPrint, true);
 127  0
     }
 128  
 
 129  
     /**
 130  
      * Print a string.  The string will be reformatted (line breaks added) as
 131  
      * necessary to reduce the odds of text being clipped on the right side of
 132  
      * the page.  The type of font (fixed or variable) is controlled by the
 133  
      * supplied boolean.
 134  
      *
 135  
      * @param aToPrint String The string to be printed.
 136  
      * @param useVariableFont boolean If true, a variable width font is used for
 137  
      *     output.  Otherwise a fixed width font is used.
 138  
      */
 139  
     public void print(String aToPrint, boolean useVariableFont) {
 140  0
         PrinterJob pj = PrinterJob.getPrinterJob();
 141  0
         PrintRequestAttributeSet attrib = new HashPrintRequestAttributeSet();
 142  
 
 143  0
         font = useVariableFont ? fontVariable : fontFixed;
 144  0
         pageLines = useVariableFont ? PAGELINESVARIABLEFONT :
 145  
                     PAGELINESFIXEDFONT;
 146  0
         pageCharsPerLine = useVariableFont ? PAGECHARSPERLINEVARIABLEFONT :
 147  
                            PAGECHARSPERLINEFIXEDFONT;
 148  0
         pageCharsVariability = useVariableFont ?
 149  
                                PAGECHARSVARIABILITYVARIABLEFONT :
 150  
                                PAGECHARSVARIABILITYFIXEDFONT;
 151  
 
 152  0
         logger.debug("aToPrint length[" + aToPrint.length() + "]");
 153  
 
 154  0
         info = parseText(aToPrint);
 155  0
         attrib.add(MediaSizeName.A);
 156  0
         attrib.add(new PageRanges(1, numPages));
 157  
 
 158  0
         logger.debug("info length[" + info.length + "]");
 159  
 
 160  0
         pj.setPrintable(this);
 161  0
         pj.setPageable(this);
 162  
 
 163  0
         if (pj.printDialog(attrib)) {
 164  
             try {
 165  0
                 pj.print(attrib);
 166  0
             } catch (Throwable any) {
 167  0
                 logger.error("Failed to print", any);
 168  0
             }
 169  
         }
 170  0
     }
 171  
 
 172  
     /**
 173  
      * Parse the input string into lines, each line being an entry in a string
 174  
      * array.  Overly long lines will be split into multiple lines.
 175  
      *
 176  
      * @param text String The string being split into lines
 177  
      * @return String[] The string with one line per array entry
 178  
      */
 179  
     private String[] parseText(String text) {
 180  0
         java.util.List tempText = new ArrayList();
 181  
         BufferedReader rdr;
 182  
         String oneLine;
 183  
         String[] allLines;
 184  
 
 185  0
         text = Utils.characterInsert(text, "\n    ", pageCharsPerLine,
 186  
                                      pageCharsPerLine + pageCharsVariability,
 187  
                                      " ");
 188  0
         rdr = new BufferedReader(new StringReader(text));
 189  
         try {
 190  0
             while ((oneLine = rdr.readLine()) != null) {
 191  0
                 tempText.add(oneLine);
 192  
             }
 193  0
         } catch (Throwable any) {
 194  
             // Nothing to do
 195  0
         } finally {
 196  0
             if (rdr != null) {
 197  
                 try {
 198  0
                     rdr.close();
 199  0
                 } catch (Throwable any) {
 200  
                     // Nothing to do
 201  0
                 }
 202  
             }
 203  0
         }
 204  
 
 205  0
         allLines = (String[]) tempText.toArray(new String[tempText.size()]);
 206  0
         numPages = allLines.length / pageLines;
 207  0
         if (allLines.length % pageLines > 0) {
 208  0
             ++numPages;
 209  
         }
 210  
 
 211  0
         logger.info("numPages[" + numPages + "]");
 212  
 
 213  0
         return allLines;
 214  
     }
 215  
 
 216  
     /**
 217  
      * Print a header on the page.  The header is centered on the top of the page
 218  
      * and a line is added beneath it.
 219  
      *
 220  
      * @param g2d Graphics2D The graphics context
 221  
      * @param lineHeight float The height of each text line
 222  
      *
 223  
      * @return float The next "Y" position that shoul be used for output
 224  
      */
 225  
     private float header(Graphics2D g2d, float lineHeight) {
 226  0
         center(g2d, title, lineHeight);
 227  0
         g2d.drawLine(0, (int) (lineHeight * 1.5),
 228  
                      g2d.getClipBounds().width, (int) (lineHeight * 1.5));
 229  0
         return lineHeight * 3;
 230  
 
 231  
     }
 232  
 
 233  
     /**
 234  
      * Print a footer on the page.  The footer is centered at the bottom of the
 235  
      * page and a line is added above it.
 236  
      *
 237  
      * @param g2d Graphics2D The graphics context
 238  
      * @param message String The message to print as the footer
 239  
      * @param startY float The starting "Y" position for the output
 240  
      * @param lineHeight float The height of each line of text
 241  
      */
 242  
     private void footer(Graphics2D g2d, String message, float startY,
 243  
                         float lineHeight) {
 244  0
         g2d.drawLine(0, (int) (startY - lineHeight),
 245  
                      g2d.getClipBounds().width, (int) (startY - lineHeight));
 246  0
         center(g2d, message, startY);
 247  0
     }
 248  
 
 249  
     /**
 250  
      * Center a message on a graphics context.
 251  
      *
 252  
      * @param g2d Graphics2D The graphics context
 253  
      * @param message String The message to center
 254  
      * @param startY float The "Y" position for the output
 255  
      */
 256  
     private void center(Graphics2D g2d, String message, float startY) {
 257  
         float width, msgWidth;
 258  
 
 259  0
         width = (float) g2d.getClipBounds().getWidth();
 260  0
         msgWidth = (float) font.getStringBounds(message,
 261  
                                                 g2d.getFontRenderContext()).
 262  
                    getWidth();
 263  
 
 264  0
         if (width > msgWidth) {
 265  0
             g2d.drawString(message, (width - msgWidth) / 2.0f, startY);
 266  
         } else {
 267  0
             g2d.drawString(message, 0, startY);
 268  
         }
 269  0
     }
 270  
 
 271  
     /**
 272  
      * Create a page of text from the parsed text.  Based on the current page
 273  
      * the relevant text lines are written to the graphics context.   The header
 274  
      * and footer are added as well.
 275  
      *
 276  
      * @param g2d Graphics2D The graphics context
 277  
      * @param page int The page number being printed (0-based)
 278  
      */
 279  
     private void paintPage(Graphics2D g2d, int page) {
 280  
         int row, dataRow;
 281  
         float lineHeight, startY;
 282  
 
 283  0
         g2d.setFont(font);
 284  0
         g2d.setColor(Color.black);
 285  0
         g2d.setPaint(Color.black);
 286  0
         lineHeight = font.getLineMetrics("Ty",
 287  
                                          g2d.getFontRenderContext()).getHeight();
 288  
 
 289  0
         startY = header(g2d, lineHeight);
 290  
 
 291  0
         dataRow = page * pageLines;
 292  
 
 293  0
         logger.info("page[" + page + "] dataRow[" + dataRow + "]");
 294  
 
 295  0
         for (row = 0; row < pageLines && dataRow < info.length; ++row,
 296  0
                    ++dataRow) {
 297  0
             g2d.drawString(info[dataRow], 0, startY);
 298  0
             startY += lineHeight;
 299  0
             logger.debug("row[" + row + "] dataRow[" + dataRow + "] startY[" +
 300  
                          startY + "]");
 301  
         }
 302  
 
 303  0
         footer(g2d, "Page: " + (page + 1) + " of " + numPages +
 304  
                "                   Format Check v." +
 305  
                ConstantsInterface.VERSION,
 306  
                (float) g2d.getClipBounds().getHeight() - lineHeight, lineHeight);
 307  0
     }
 308  
 
 309  
     // Begin interface Printable
 310  
 
 311  
     public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
 312  0
         if (pageIndex >= numPages) {
 313  0
             return (NO_SUCH_PAGE);
 314  
         } else {
 315  0
             Graphics2D g2d = (Graphics2D) g;
 316  0
             g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
 317  0
             paintPage(g2d, pageIndex);
 318  0
             return (PAGE_EXISTS);
 319  
         }
 320  
     }
 321  
 
 322  
     // End Interface Printable
 323  
 
 324  
     // Begin Interface Pageable
 325  
 
 326  
     public int getNumberOfPages() {
 327  0
         return numPages;
 328  
     }
 329  
 
 330  
     public PageFormat getPageFormat(int pageIndex) {
 331  0
         return new PageFormat();
 332  
     }
 333  
 
 334  
     public Printable getPrintable(int pageIndex) {
 335  0
         return this;
 336  
     }
 337  
 
 338  
     // End Interface Pageable
 339  
 
 340  
 }