From: <doc...@us...> - 2007-09-25 23:57:34
|
Revision: 177 http://openpcl.svn.sourceforge.net/openpcl/?rev=177&view=rev Author: documentsystems Date: 2007-09-25 16:57:34 -0700 (Tue, 25 Sep 2007) Log Message: ----------- Howard Hoagland. New class made by Jim Gabriel 9/18/07, then modified by Howard Hoagland 9/18 to 9/25. The purpose of this class is to handle the printing of a PCL bytestream to the printer, whether it uses PCLDirect or GDI. PCLDirect is the fastest but requires the printer selected to handle PCL 5 or higher. GDI is compatible with all printers but is slower since each page must be rendered before being sent to the printer. 9/18/07 to 9/25/07 Howard Hoagland. Changed significantly to make it work with OpenPCLViewer and PosPrintPages so that printing PCL Direct and Windows Print uses this class only and doesn't use PosPrintBufferedImage and PosPrintPageableInterface, because this class implements the methods of both those Interfaces and in fact the code from those two classes was cut and pasted into this class to make it do the job of those two. The main benefit of this class is to implement printing duplex for Windows Print. Added Paths: ----------- openpcl/src/com/openpcl/viewer/printing/PCLPrintJob.java Added: openpcl/src/com/openpcl/viewer/printing/PCLPrintJob.java =================================================================== --- openpcl/src/com/openpcl/viewer/printing/PCLPrintJob.java (rev 0) +++ openpcl/src/com/openpcl/viewer/printing/PCLPrintJob.java 2007-09-25 23:57:34 UTC (rev 177) @@ -0,0 +1,553 @@ +package com.openpcl.viewer.printing; + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.RenderingHints; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.awt.image.ImageObserver; +import java.awt.print.PageFormat; +import java.awt.print.Pageable; +import java.awt.print.Paper; +import java.awt.print.Printable; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Locale; + +import javax.print.PrintException; +import javax.print.SimpleDoc; +import javax.print.DocFlavor; +import javax.print.DocPrintJob; +import javax.print.PrintService; + +import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; +import javax.print.attribute.standard.Chromaticity; +import javax.print.attribute.standard.JobKOctets; +import javax.print.attribute.standard.JobName; +import javax.print.attribute.standard.MediaPrintableArea; +import javax.print.attribute.standard.MediaSizeName; +import javax.print.attribute.standard.OrientationRequested; +import javax.print.attribute.standard.PrintQuality; +import javax.print.attribute.standard.Sides; +import javax.swing.JOptionPane; +import javax.swing.JProgressBar; + +import com.openpcl.pclrenderimage.render.PriPageSettings; +import com.openpcl.pclrenderimage.util.PriDebug; +import com.openpcl.pclrenderimage.PclRenderImage; + +/** +* The purpose of this class is to handle the printing of a PCL bytestream to the printer, whether it uses +* PCLDirect or GDI. PCLDirect is the fastest but requires the printer selected to handle PCL 5 or higher. +* GDI is compatible with all printers but is slower since each page must be rendered before being sent to the printer. +* +* @author DocMagic, Document Systems Inc, Jim Gabriel. Sept 18, 2007 +* +* 9/18/07 to 9/25/07 Howard Hoagland. Changed significantly to make it work with OpenPCLViewer and PosPrintPages +* so that printing PCL Direct and Windows Print uses this class only and doesn't use PosPrintBufferedImage +* and PosPrintPageableInterface, because this class implements the methods of both those Interfaces and in fact +* the code from those two classes was cut and pasted into this class to make it do the job of those two. The main benefit +* of this class is to implement printing duplex for Windows Print. +* +* Helpful reference URLs used to create and design this class<br> +* http://www.javaworld.com/javaworld/jw-10-2000/jw-1020-print.html<br> +* http://java.sun.com/products/java-media/2D/forDevelopers/sdk12print.html<br> +* http://www.java2s.com/Code/Java/2D-Graphics-GUI/PageableText.htm<br> +*/ +public class PCLPrintJob implements Pageable, Printable, ImageObserver { + + enum PrintModeEnum { PrintModePCLDirect, PrintModeGDI }; + enum OutputPageSizeEnum { OutputPageSizeAsSpecifiedInPCL, OutputPageSizeAllOnLetter, OutputPageSizeAllOnLegal }; + + protected ByteArrayOutputStream mByteArrayOutputStream; + private PrinterJob mPrinterJob; + private BufferedImage mImageToPrintOn = null; + private AffineTransform mOrigAffineTransform = null; + private AffineTransform mScaleAffineTransform = null; + protected PrintService mPrintService = null; + protected PclRenderImage mPrintDocGDI = null; // only needed for GDI printing + private Paper mLetterPaperPortrait = null; + private Paper mLegalPaperPortrait = null; + protected int mPagesPrinted = 0; + protected String mCurrentPageSize = ""; + protected boolean mPrintAllOnLegal = false; + protected String mPrintJobName = ""; + protected PrintRequestAttributeSet mAttr = null; + protected String mLastFormName = ""; + protected int mLastPageNumber = 0; + protected boolean mIsDuplex = false; + private double mPrintScale = 72.0d / 300.0d; + private JProgressBar mPrintingProgressBar = null; + private static final String sProgressBarBaseString = "Generating page: "; + private static final String sCantAllocate = "Can't allocate memory for temporary image used for printing."; + + // Enums are PrintModePCLDirect, PrintModeGDI + public PrintModeEnum mPrintModeEnum; + + // Enums are OutputPageSizeAsSpecifiedInPCL, OutputPageSizeAllOnLetter, OutputPageSizeAllOnLegal + public OutputPageSizeEnum mOutputPageSizeEnum; + + // required for shrinking legal to letter when GDI printing + private AffineTransform mShrinkLegalToLetter = null; + private double mPageWidthPixels = 8.5 * 300; + private double mShrinkLegalToLetterRatio = (11.0d / 14.0d); // shrink in both directions height 14" to 11" + private double mShrinkLegalToLetterScale = mPrintScale * mShrinkLegalToLetterRatio; + private double mShrinkLegalToLetterMargins = 0.27d * 300.0d; + private double mXOffsetForCenteringShrinkLegalOnLetter = + ((mPageWidthPixels - (mPageWidthPixels * mShrinkLegalToLetterRatio)) / 2) + mShrinkLegalToLetterMargins; + + /** Constructor */ + public PCLPrintJob() { + mPrintDocGDI = new PclRenderImage(); + + // Letter size portrait with .2 inch margins + mLetterPaperPortrait = new Paper(); + mLetterPaperPortrait.setSize(8.5d * 72, 11.0d * 72); + mLetterPaperPortrait.setImageableArea(.18d * 72, .18d * 72, 8.14d * 72, 10.64d * 72); + + // Legal size portraint with .2 inch margins + mLegalPaperPortrait = new Paper(); + mLegalPaperPortrait.setSize(8.5d * 72, 14.0d * 72); + mLegalPaperPortrait.setImageableArea(.18d * 72, .18d * 72, 8.14d * 72, 13.64d * 72); + + mScaleAffineTransform = AffineTransform.getScaleInstance(mPrintScale, mPrintScale); + mShrinkLegalToLetter = AffineTransform.getScaleInstance(mShrinkLegalToLetterScale, mShrinkLegalToLetterScale); + + mImageToPrintOn = createNewBWBufferedImageToPrintOn(); + + //Set the default choices on the print dialog for portrait, Legal, one sided, 4 margins + mAttr = new HashPrintRequestAttributeSet(); + mAttr.add(OrientationRequested.PORTRAIT); + + // Don't set to "DRAFT" or else the print driver picks the lowest resolution the printer can do. + mAttr.add(PrintQuality.HIGH); + + mAttr.add(MediaSizeName.NA_LEGAL); + mAttr.add(new MediaPrintableArea(0.20f, 0.20f, 8.1f, 13.6f, MediaPrintableArea.INCH)); + mAttr.add(Chromaticity.MONOCHROME); + + mAttr.add(new JobKOctets((int)(256))); // Total job K bytes. Default but is changed at print time with the exact number + mAttr.add(Sides.ONE_SIDED); // Default but is changed in the Printable.print() callback and when setDuplex() is called + mAttr.add(new JobName("PCL print", Locale.getDefault())); // Default but is changed when setPrintJobName(String) is called + } + + public PrintRequestAttributeSet getPrintRequestAttributeSet() { return mAttr; } + + /** + * Pass in parameters needed to initialize the printing for the next printout. + * @param pPrintMode + * @param pOutputPageSize + * @param pPrintJobName + * @param pPCLData + * @param pPrinterJob + * @param pIsDuplex + */ + public void initializePrintJob(PrintModeEnum pPrintModeEnum, OutputPageSizeEnum pOutputPageSizeEnum, + String pPrintJobName, byte[] pPCLData, PrinterJob pPrinterJob) { + mByteArrayOutputStream = new ByteArrayOutputStream(); + mPrinterJob = pPrinterJob; + + // Get the PrintService out of the passed in PrinterJob + mPrintService = mPrinterJob.getPrintService(); + + setPCLDataToPrint(pPCLData); + setPrintMode(pPrintModeEnum, pOutputPageSizeEnum); + setPrintJobName(pPrintJobName); + } + + private void setPCLDataToPrint(byte[] pPCLData) { + try { + mByteArrayOutputStream.write(pPCLData); + } catch (IOException e) { + System.out.println("Error. Can't set the bytes to print in Class PCLPrintJob, method is setPCLDataToPrint(byte[]). "); + } + } + + private void setPrintMode (PrintModeEnum pPrintModeEnum, OutputPageSizeEnum pOutputPageSizeEnum ) { + mPrintModeEnum=pPrintModeEnum; + mOutputPageSizeEnum = pOutputPageSizeEnum; + + switch (mPrintModeEnum) { + case PrintModeGDI : { + + // Take the stream and break it up into pages + mPrintDocGDI.splitIntoSeparatePclPages(mByteArrayOutputStream.toByteArray()); + System.out.println("setPrintMode() GDI printing " + mPrintDocGDI.getPclPageCount() + " pages total"); + + // Set duplex mode here from if the multi page PCL bytes parsed in the above splitIntoSeparatePclPages() had "duplex on" + setIsDuplex(mPrintDocGDI.getPriPageSettings().getIsDuplexMode()); + + // DO NOT CALL setPrintable since this will be set in the getPrintable method + mPrinterJob.setPageable(this); + break; + } + case PrintModePCLDirect : { + // Important: "All on Letter" works for GDI Windows Print, and not for PCL Direct because it's possible to shrink the image + // to fit a Legal image on Letter paper, but to do this for PCL Direct, all the PCL (x,y) positioning and drawing sizes would + // need to be modified, which would make the resulting image printed on paper not exact + System.out.println("setPrintMode() Pcl Direct printing " + mByteArrayOutputStream.size() + " bytes"); + mPrinterJob.setPrintable(this); + break; + } + default : mPrinterJob.setPrintable(this); + } + } + + /** Pass in the printjob name how it is displayed in the job queue. */ + private void setPrintJobName(String pPrintJobName) { + mPrintJobName=pPrintJobName; + mAttr.add(new JobName(mPrintJobName, Locale.getDefault())); + } + + /** If the PCL doesn't have the duplex codes in it, you can still print DUPLEX GDI. + * This has no affect when doing PCL Direct (sending the PCL directly to the printer). */ + private void setIsDuplex(boolean pIsDuplex) { + mIsDuplex = pIsDuplex; + if (mIsDuplex) { + mAttr.add(Sides.TWO_SIDED_LONG_EDGE); + } else { + mAttr.add(Sides.ONE_SIDED); + } + } + + /** + *This is the main CALLBACK method for the java.awt.print.Prinable interface + * Note that the page number passed in is 0 based. + */ + public int print(Graphics pGraphics, PageFormat pPageFormat, int pPageNumber) throws PrinterException { + Graphics2D tGraphics2DToPrintOn = null; + BufferedImage tBufferedColorImage = null; + SimpleDoc tSimpleDoc = null; + DocFlavor tDocFlavor = DocFlavor.INPUT_STREAM.AUTOSENSE; + ByteArrayInputStream tByteArrayInputStream = null; + DocPrintJob tDocPrintJob = null; + boolean tShouldSetRenderingHints = false; + + switch (mPrintModeEnum) { + case PrintModePCLDirect : { + System.out.println("PCL Direct"); + + // The input stream for the DocPrintJob + if (mByteArrayOutputStream == null || mByteArrayOutputStream.size() < 1) { return Printable.NO_SUCH_PAGE; } + + tByteArrayInputStream = new ByteArrayInputStream(mByteArrayOutputStream.toByteArray()); + tSimpleDoc = new SimpleDoc(tByteArrayInputStream, tDocFlavor, null); + + if (tSimpleDoc == null) { return Printable.NO_SUCH_PAGE; } + if (mPrintService == null) { return Printable.NO_SUCH_PAGE; } + + tDocPrintJob = mPrintService.createPrintJob(); + if (tDocPrintJob == null) { return Printable.NO_SUCH_PAGE; } + + try { + tDocPrintJob.print(tSimpleDoc, mAttr); + } catch (PrintException e) { + PriDebug.error("In class PCLPrintJob, PrintException trying to print PCL Direct.", e); + return Printable.NO_SUCH_PAGE; + } + + // Update the progress bar once because the byte[] was sent to the printer no matter how many pages + if (mPrintingProgressBar != null) { + mPrintingProgressBar.setValue(mPrintingProgressBar.getMaximum()); + mPrintingProgressBar.setString(sProgressBarBaseString + (mPrintingProgressBar.getMaximum()) + + " of " + mPrintingProgressBar.getMaximum()); + } + + // All the pages printed out because all the pages were sent to the printer all at one time above. + // Returning NO_SUCH_PAGE makes the JDK printing not call this callback method later, so this terminates the printing. + return Printable.NO_SUCH_PAGE; + } + + case PrintModeGDI : { + System.out.println("GDI printing pg " + (pPageNumber + 1) + " of " + mPrintDocGDI.getPclPageCount()); + + if ((pPageNumber < 0) || (pPageNumber >= mPrintDocGDI.getPclPageCount())) { + return Printable.NO_SUCH_PAGE; + } + + // Cast passed in Graphics to Graphics2D + Graphics2D g2D = (Graphics2D)pGraphics; + // Set rendering hints + if (tShouldSetRenderingHints) { setRenderingHints(g2D); } + // Set background color white + g2D.setBackground(Color.WHITE); + // Make drawing text and rectangles and pixels be in black + g2D.setPaint(Color.BLACK); + // Save the passed in AffineTransform (to put it back before returning) + mOrigAffineTransform = g2D.getTransform(); + + String tPageSizeInPCL = mPrintDocGDI.getPaperSizeForPage(pPageNumber + 1); + String tPageSize = tPageSizeInPCL; + + switch(mOutputPageSizeEnum) { + + case OutputPageSizeAllOnLetter : { + tPageSize = "LTR"; + if (tPageSizeInPCL == "LGL") { + // Original size was Legal, but need to shrink down to Letter size. + // The method getPageFormat() in this class PCLPrintJob returns Letter when "All on Letter" and original size was Legal. + g2D.transform(mShrinkLegalToLetter); + // Center the Legal image on the Letter page size buy bumping to + // the right half the available horizontal space + g2D.translate(mXOffsetForCenteringShrinkLegalOnLetter, 0.0d); + } else { + // Set the 72/300 = .24 AffineTransform on the current Graphics2D, to scale smaller to fit exactly on the printed page + g2D.transform(mScaleAffineTransform); + } + break; + } + + case OutputPageSizeAllOnLegal : { + tPageSize = "LGL"; + g2D.transform(mScaleAffineTransform); + break; + } + + case OutputPageSizeAsSpecifiedInPCL : + // Set the 72/300 = .24 AffineTransform on the current Graphics2D, to scale smaller to fit exactly on the printed page + g2D.transform(mScaleAffineTransform); + } + + if (mImageToPrintOn != null) { tGraphics2DToPrintOn = mImageToPrintOn.createGraphics(); } + + // Draw the screen image on the printer Graphics2D using the scale down transform + byte[] tPrintTimeBytes = new byte[1]; + tBufferedColorImage = mPrintDocGDI.getImageForPage(pPageNumber + 1, tPrintTimeBytes, true, tPageSize, 1.00d); + + if (tBufferedColorImage == null) { + // The image for this page is blank page because two form feeds are together when duplexing to force a blank back page. + tGraphics2DToPrintOn.setPaint(Color.WHITE); + // Draw a white rectangle 8.5 inches by 14 inches which blanks out the image + tGraphics2DToPrintOn.fillRect(0, 0, PriPageSettings.sNumPixels85Inches, PriPageSettings.sNumPixels14Inches); + + } else { + // Convert to 2 color black and white, so that the file in the print queue is smaller and prints faster + tGraphics2DToPrintOn.drawImage(tBufferedColorImage, 0, 0, this); + } + + // Draw the image on the printer Graphics2D using the scale down transform + g2D.drawImage(mImageToPrintOn, 0, 0, this); + + // Revert back to the passed in AffineTransform because the JDK doc for printing says put back the + // passed in Graphics object's settings back if you modified it in this Printable interface print() callback + g2D.transform(mOrigAffineTransform); + + // Update the progress bar at each page + if (mPrintingProgressBar != null) { + mPrintingProgressBar.setValue(pPageNumber + 1); + mPrintingProgressBar.setString(sProgressBarBaseString + (pPageNumber + 1) + " of " + mPrintingProgressBar.getMaximum()); + } + + return Printable.PAGE_EXISTS; + } + default : + return Printable.NO_SUCH_PAGE; + } + } + + /** + * Create a new BufferredImage all ready to print on + * @return BufferedImage + */ + private BufferedImage createNewBWBufferedImageToPrintOn() { + BufferedImage tToPrintOnBufferedImage = null; + try { + tToPrintOnBufferedImage = new BufferedImage ( + PriPageSettings.sNumPixels85Inches, // make the BufferedImage be 8.5 inches by 14 inches + PriPageSettings.sNumPixels14Inches, + BufferedImage.TYPE_BYTE_BINARY); // 2 color only image is black and white (not full color) for printing not on screen + } catch (OutOfMemoryError e1) { + tToPrintOnBufferedImage = null; + JOptionPane.showMessageDialog(null, "Out of heap space memory. " + sCantAllocate , "Heap space memory", + JOptionPane.ERROR_MESSAGE); + + } catch (Error e2) { + tToPrintOnBufferedImage = null; + JOptionPane.showMessageDialog(null, "Error. " + sCantAllocate , "Error", + JOptionPane.ERROR_MESSAGE); + + } catch (Exception e3) { + tToPrintOnBufferedImage = null; + JOptionPane.showMessageDialog(null, "Exception. " + sCantAllocate , "Exception", + JOptionPane.ERROR_MESSAGE); + } + return tToPrintOnBufferedImage; + } + + public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h) { + if ( (infoflags & ALLBITS) != 0 ) { + // The image drawing has completed + return false; + } else { + // The image is still drawing + return true; + } + } + + public int getNumberOfPages() { + // System.out.println("getNumberOfPages called"); + switch (mPrintModeEnum) { + case PrintModeGDI : {return mPrintDocGDI.getPclPageCount(); } + default : { return 10000; } + } + } + + public Printable getPrintable(int pForPageNumber) throws IndexOutOfBoundsException { + if (pForPageNumber >= mPrintDocGDI.getPclPageCount()) { + throw new IndexOutOfBoundsException( + makeIndexOutOfBoundsInfoString(pForPageNumber, mPrintDocGDI.getPclPageCount())); + } else { + return this; + } + } + + public PageFormat getPageFormat(int pPageNumber) throws IndexOutOfBoundsException { + PageFormat tBuiltPageFormat = new PageFormat(); + switch (mPrintModeEnum) { + + case PrintModeGDI : { + if (pPageNumber >= mPrintDocGDI.getPclPageCount()) { + throw new IndexOutOfBoundsException( + makeIndexOutOfBoundsInfoString(pPageNumber, mPrintDocGDI.getPclPageCount())); + + } else { + // If original page size was Letter, or if "Print all on Letter" even for pages that are Legal size, return Letter size + if ((mPrintDocGDI.getPaperSizeForPage(pPageNumber + 1) == "LTR") || + (mOutputPageSizeEnum == OutputPageSizeEnum.OutputPageSizeAllOnLetter)) { + tBuiltPageFormat.setPaper(mLetterPaperPortrait); + + } else { + tBuiltPageFormat.setPaper(mLegalPaperPortrait); + } + } + System.out.println("getPageFormat called for page " + pPageNumber + + " size = " + mPrintDocGDI.getPaperSizeForPage(pPageNumber + 1) ); + break; + } + + default : + tBuiltPageFormat.setPaper(mLegalPaperPortrait); + } + return tBuiltPageFormat; + } + + private String makeIndexOutOfBoundsInfoString(int pForPageNumber, int pNumberOfPages) { + return ("Not allowed to print page #" + (pForPageNumber + 1) + " because only " + + pNumberOfPages + (pNumberOfPages == 1 ? "page was" : "pages were)" ) + + " selected to print."); + } + + private void setRenderingHints(Graphics2D pG2D) { + // Turn on antialiasing + pG2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + pG2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + // Pick text quality instead of speed + pG2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + // Turn dithering on. Dithering approximates color values by drawing groups of pixels of similar colors + pG2D.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE); + // Alpha composites for Quality + pG2D.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); + // Turn the computation of fractional character dimensions on. + // Fractional character dimensions lead to better placement of characters + pG2D.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); + // Select quality or speed for color rendering. + pG2D.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); + // Interpolating pixels when scaling or rotating images. + pG2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); + // Combining strokes + pG2D.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE); + } + + public void setPrintingProgressBar(JProgressBar pPrintingProgressBar) { + mPrintingProgressBar = pPrintingProgressBar; + } + + /** Used only for unit testing from the main() in this class. Returns the contents of the file in a byte array. */ + private static byte[] getBytesFromFile(File file) throws IOException { + InputStream tInputStream = new FileInputStream(file); + + // Note that the lengh of the file returned from java.io.File.lenght() is a long, not an int + long tFileLength = file.length(); + + // You cannot create an array using a long type. It needs to be an int type. + // Before converting to an int type, check to ensure that file is not larger than Integer.MAX_VALUE. + if (tFileLength > Integer.MAX_VALUE) { tFileLength = Integer.MAX_VALUE; } + + // Create the byte array to hold the data + byte[] tFileBytes = new byte[(int)tFileLength]; + + // Read in the bytes + int tOffset = 0; + int tNumBytesRead = 0; + while (tOffset < tFileBytes.length + && (tNumBytesRead = tInputStream.read(tFileBytes, tOffset, tFileBytes.length - tOffset)) >= 0) { + tOffset += tNumBytesRead; + } + + // Ensure all the bytes have been read in + if (tOffset < tFileBytes.length) { + throw new IOException("Could not completely read file "+file.getName()); + } + + // Close the input stream and return bytes + tInputStream.close(); + return tFileBytes; + } + + /** + * The main() here is for unit testing and to show how to use this class from the app using this class. + * @param args + */ + public static void main(String[] args) { + byte[] tFileByteArray = null; + + String tFileName = "c:/temp/ltrlegal.DBK"; + try { + // If you have a PCL diskfile, load it here + tFileByteArray = getBytesFromFile(new File(tFileName)); + } catch (IOException e) { + System.out.println("IOException reading bytes from file: " + tFileName ); + } + + // Be sure the program sets the number of pages from 1 to 1000 so that + // the print call back routine can control the number of loops. + PrinterJob tPrinterJob = PrinterJob.getPrinterJob(); + + // Call the constructor once for all print jobs. Don't do a "new PCLPrintJob()" for each printout. + PCLPrintJob tPCLPrintJob = new PCLPrintJob(); + + // Until we have the ability to retrieve the DUPLEX flag from PCLRender image, + // we'll just set it here. This is only has effect for GDI printing. + tPCLPrintJob.setIsDuplex(true); + + boolean tUserHitOK = tPrinterJob.printDialog(); + if (tUserHitOK) { + + // Call the initializePrintJob(...) for each printout + tPCLPrintJob.initializePrintJob(PrintModeEnum.PrintModeGDI, // Tell the object whether GDI or PCLDirect + // With GDI, you can set all the forms to print on LETTER, or on LEGAL or as defined in the PCL + OutputPageSizeEnum.OutputPageSizeAllOnLetter , + "Testing PCLPrintJob.java", // This is the job name as it will appear in the print queue + tFileByteArray, // The PCL bytes get sent here + tPrinterJob // This is the job + ); + + try { + tPrinterJob.print(tPCLPrintJob.getPrintRequestAttributeSet()); + } catch (PrinterException ex) { + // The job did not successfully complete + System.out.println("PrinterException calling PCLPrintJob"); + } + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |