/* * Copyright (c) 1998, 2008, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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. */ package sun.print; import java.io.FilePermission; import java.awt.Color;import java.awt.Dialog;import java.awt.Frame;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.GraphicsConfiguration;import java.awt.GraphicsEnvironment;import java.awt.HeadlessException;import java.awt.KeyboardFocusManager;import java.awt.Rectangle;import java.awt.Shape;import java.awt.geom.AffineTransform;import java.awt.geom.Area;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.awt.image.BufferedImage;import java.awt.print.Book;import java.awt.print.Pageable;import java.awt.print.PageFormat;import java.awt.print.Paper;import java.awt.print.Printable;import java.awt.print.PrinterAbortException;import java.awt.print.PrinterException;import java.awt.print.PrinterJob;import java.awt.Window;import java.io.File;import java.io.IOException;import java.util.ArrayList;import java.util.Enumeration;import java.util.Locale;import sun.awt.image.ByteInterleavedRaster; import javax.print.Doc;import javax.print.DocFlavor;import javax.print.DocPrintJob;import javax.print.PrintException;import javax.print.PrintService;import javax.print.PrintServiceLookup;import javax.print.ServiceUI;import javax.print.StreamPrintService;import javax.print.StreamPrintServiceFactory;import javax.print.attribute.Attribute;import javax.print.attribute.AttributeSet;import javax.print.attribute.HashPrintRequestAttributeSet;import javax.print.attribute.PrintRequestAttributeSet;import javax.print.attribute.Size2DSyntax;import javax.print.attribute.standard.Chromaticity;import javax.print.attribute.standard.Copies;import javax.print.attribute.standard.Destination;import javax.print.attribute.standard.DialogTypeSelection;import javax.print.attribute.standard.Fidelity;import javax.print.attribute.standard.JobName;import javax.print.attribute.standard.JobSheets;import javax.print.attribute.standard.Media;import javax.print.attribute.standard.MediaPrintableArea;import javax.print.attribute.standard.MediaSize;import javax.print.attribute.standard.MediaSizeName;import javax.print.attribute.standard.OrientationRequested;import javax.print.attribute.standard.PageRanges;import javax.print.attribute.standard.PrinterState;import javax.print.attribute.standard.PrinterStateReason;import javax.print.attribute.standard.PrinterStateReasons;import javax.print.attribute.standard.PrinterIsAcceptingJobs;import javax.print.attribute.standard.RequestingUserName;import javax.print.attribute.standard.SheetCollate;import javax.print.attribute.standard.Sides; import sun.print.PageableDoc;import sun.print.ServiceDialog;import sun.print.SunPrinterJobService;import sun.print.SunPageSelection; /** * A class which rasterizes a printer job. * * @author Richard Blanchard */public abstract class RasterPrinterJob extends PrinterJob { /* Class Constants */ /* Printer destination type. */ protected static final int PRINTER = 0; /* File destination type. */ protected static final int FILE = 1; /* Stream destination type. */ protected static final int STREAM = 2; /** * Maximum amount of memory in bytes to use for the * buffered image "band". 4Mb is a compromise between * limiting the number of bands on hi-res printers and * not using too much of the Java heap or causing paging * on systems with little RAM. */ private static final int MAX_BAND_SIZE = (1024 * 1024 * 4); /* Dots Per Inch */ private static final float DPI = 72.0f; /** * Useful mainly for debugging, this system property * can be used to force the printing code to print * using a particular pipeline. The two currently * supported values are FORCE_RASTER and FORCE_PDL. */ private static final String FORCE_PIPE_PROP = "sun.java2d.print.pipeline"; /** * When the system property FORCE_PIPE_PROP has this value * then each page of a print job will be rendered through * the raster pipeline. */ private static final String FORCE_RASTER = "raster"; /** * When the system property FORCE_PIPE_PROP has this value * then each page of a print job will be rendered through * the PDL pipeline. */ private static final String FORCE_PDL = "pdl"; /** * When the system property SHAPE_TEXT_PROP has this value * then text is always rendered as a shape, and no attempt is made * to match the font through GDI */ private static final String SHAPE_TEXT_PROP = "sun.java2d.print.shapetext"; /** * values obtained from System properties in static initialiser block */ public static boolean forcePDL = false; public static boolean forceRaster = false; public static boolean shapeTextProp = false; static { /* The system property FORCE_PIPE_PROP * can be used to force the printing code to * use a particular pipeline. Either the raster * pipeline or the pdl pipeline can be forced. */ String forceStr = (String)java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction(FORCE_PIPE_PROP)); if (forceStr != null) { if (forceStr.equalsIgnoreCase(FORCE_PDL)) { forcePDL = true; } else if (forceStr.equalsIgnoreCase(FORCE_RASTER)) { forceRaster = true; } } String shapeTextStr = (String)java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction(SHAPE_TEXT_PROP)); if (shapeTextStr != null) { shapeTextProp = true; } } /* Instance Variables */ /** * Used to minimise GC & reallocation of band when printing */ private int cachedBandWidth = 0; private int cachedBandHeight = 0; private BufferedImage cachedBand = null; /** * The number of book copies to be printed. */ private int mNumCopies = 1; /** * Collation effects the order of the pages printed * when multiple copies are requested. For two copies * of a three page document the page order is: * mCollate true: 1, 2, 3, 1, 2, 3 * mCollate false: 1, 1, 2, 2, 3, 3 */ private boolean mCollate = false; /** * The zero based indices of the first and last * pages to be printed. If 'mFirstPage' is * UNDEFINED_PAGE_NUM then the first page to * be printed is page 0. If 'mLastPage' is * UNDEFINED_PAGE_NUM then the last page to * be printed is the last one in the book. */ private int mFirstPage = Pageable.UNKNOWN_NUMBER_OF_PAGES; private int mLastPage = Pageable.UNKNOWN_NUMBER_OF_PAGES; /** * The previous print stream Paper * Used to check if the paper size has changed such that the * implementation needs to emit the new paper size information * into the print stream. * Since we do our own rotation, and the margins aren't relevant, * Its strictly the dimensions of the paper that we will check. */ private Paper previousPaper; /** * The document to be printed. It is initialized to an * empty (zero pages) book. */ private Pageable mDocument = new Book(); /** * The name of the job being printed. */ private String mDocName = "Java Printing"; /** * Printing cancellation flags */ private boolean performingPrinting = false; private boolean userCancelled = false; /** * Print to file permission variables. */ private FilePermission printToFilePermission; /** * List of areas & the graphics state for redrawing */ private ArrayList redrawList = new ArrayList(); /* variables representing values extracted from an attribute set. * These take precedence over values set on a printer job */ private int copiesAttr; private String jobNameAttr; private String userNameAttr; private PageRanges pageRangesAttr; protected Sides sidesAttr; protected String destinationAttr; protected boolean noJobSheet = false; protected int mDestType = RasterPrinterJob.FILE; protected String mDestination = ""; protected boolean collateAttReq = false; /** * Device rotation flag, if it support 270, this is set to true; */ protected boolean landscapeRotates270 = false; /** * attributes used by no-args page and print dialog and print method to * communicate state */ protected PrintRequestAttributeSet attributes = null; /** * Class to keep state information for redrawing areas * "region" is an area at as a high a resolution as possible. * The redrawing code needs to look at sx, sy to calculate the scale * to device resolution. */ private class GraphicsState { Rectangle2D region; // Area of page to repaint Shape theClip; // image drawing clip. AffineTransform theTransform; // to transform clip to dev coords. double sx; // X scale from region to device resolution double sy; // Y scale from region to device resolution } /** * Service for this job */ protected PrintService myService; /* Constructors */ public RasterPrinterJob() { } /* Abstract Methods */ /** * Returns the resolution in dots per inch across the width * of the page. */ abstract protected double getXRes(); /** * Returns the resolution in dots per inch down the height * of the page. */ abstract protected double getYRes(); /** * Must be obtained from the current printer. * Value is in device pixels. * Not adjusted for orientation of the paper. */ abstract protected double getPhysicalPrintableX(Paper p); /** * Must be obtained from the current printer. * Value is in device pixels. * Not adjusted for orientation of the paper. */ abstract protected double getPhysicalPrintableY(Paper p); /** * Must be obtained from the current printer. * Value is in device pixels. * Not adjusted for orientation of the paper. */ abstract protected double getPhysicalPrintableWidth(Paper p); /** * Must be obtained from the current printer. * Value is in device pixels. * Not adjusted for orientation of the paper. */ abstract protected double getPhysicalPrintableHeight(Paper p); /** * Must be obtained from the current printer. * Value is in device pixels. * Not adjusted for orientation of the paper. */ abstract protected double getPhysicalPageWidth(Paper p); /** * Must be obtained from the current printer. * Value is in device pixels. * Not adjusted for orientation of the paper. */ abstract protected double getPhysicalPageHeight(Paper p); /** * Begin a new page. */ abstract protected void startPage(PageFormat format, Printable painter, int index, boolean paperChanged) throws PrinterException; /** * End a page. */ abstract protected void endPage(PageFormat format, Printable painter, int index) throws PrinterException; /** * Prints the contents of the array of ints, 'data' * to the current page. The band is placed at the * location (x, y) in device coordinates on the * page. The width and height of the band is * specified by the caller. */ abstract protected void printBand(byte[] data, int x, int y, int width, int height) throws PrinterException; /* Instance Methods */ /** * save graphics state of a PathGraphics for later redrawing * of part of page represented by the region in that state */ public void saveState(AffineTransform at, Shape clip, Rectangle2D region, double sx, double sy) { GraphicsState gstate = new GraphicsState(); gstate.theTransform = at; gstate.theClip = clip; gstate.region = region; gstate.sx = sx; gstate.sy = sy; redrawList.add(gstate); } /* * A convenience method which returns the default service * for 2D <code>PrinterJob</code>s. * May return null if there is no suitable default (although there * may still be 2D services available). * @return default 2D print service, or null. * @since 1.4 */ protected static PrintService lookupDefaultPrintService() { PrintService service = PrintServiceLookup.lookupDefaultPrintService(); /* Pageable implies Printable so checking both isn't strictly needed */ if (service != null && service.isDocFlavorSupported( DocFlavor.SERVICE_FORMATTED.PAGEABLE) && service.isDocFlavorSupported( DocFlavor.SERVICE_FORMATTED.PRINTABLE)) { return service; } else { PrintService []services = PrintServiceLookup.lookupPrintServices( DocFlavor.SERVICE_FORMATTED.PAGEABLE, null); if (services.length > 0) { return services[0]; } } return null; } /** * Returns the service (printer) for this printer job. * Implementations of this class which do not support print services * may return null; * @return the service for this printer job. * */ public PrintService getPrintService() { if (myService == null) { PrintService svc = PrintServiceLookup.lookupDefaultPrintService(); if (svc != null && svc.isDocFlavorSupported( DocFlavor.SERVICE_FORMATTED.PAGEABLE)) { try { setPrintService(svc); myService = svc; } catch (PrinterException e) { } } if (myService == null) { PrintService[] svcs = PrintServiceLookup.lookupPrintServices( DocFlavor.SERVICE_FORMATTED.PAGEABLE, null); if (svcs.length > 0) { try { setPrintService(svcs[0]); myService = svcs[0]; } catch (PrinterException e) { } } } } return myService; } /** * Associate this PrinterJob with a new PrintService. * * Throws <code>PrinterException</code> if the specified service * cannot support the <code>Pageable</code> and * <code>Printable</code> interfaces necessary to support 2D printing. * @param a print service which supports 2D printing. * * @throws PrinterException if the specified service does not support * 2D printing or no longer available. */ public void setPrintService(PrintService service) throws PrinterException { if (service == null) { throw new PrinterException("Service cannot be null"); } else if (!(service instanceof StreamPrintService) && service.getName() == null) { throw new PrinterException("Null PrintService name."); } else { // Check the list of services. This service may have beenLines 1–500 of 2283. Load more
/* * Copyright (c) 1998, 2008, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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. */ package sun.print; import java.io.FilePermission; import java.awt.Color; import java.awt.Dialog; import java.awt.Frame; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.GraphicsEnvironment; import java.awt.HeadlessException; import java.awt.KeyboardFocusManager; import java.awt.Rectangle; import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.geom.Area; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.awt.print.Book; import java.awt.print.Pageable; import java.awt.print.PageFormat; import java.awt.print.Paper; import java.awt.print.Printable; import java.awt.print.PrinterAbortException; import java.awt.print.PrinterException; import java.awt.print.PrinterJob; import java.awt.Window; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Enumeration; import java.util.Locale; import sun.awt.image.ByteInterleavedRaster; import javax.print.Doc; import javax.print.DocFlavor; import javax.print.DocPrintJob; import javax.print.PrintException; import javax.print.PrintService; import javax.print.PrintServiceLookup; import javax.print.ServiceUI; import javax.print.StreamPrintService; import javax.print.StreamPrintServiceFactory; import javax.print.attribute.Attribute; import javax.print.attribute.AttributeSet; import javax.print.attribute.HashPrintRequestAttributeSet; import javax.print.attribute.PrintRequestAttributeSet; import javax.print.attribute.Size2DSyntax; import javax.print.attribute.standard.Chromaticity; import javax.print.attribute.standard.Copies; import javax.print.attribute.standard.Destination; import javax.print.attribute.standard.DialogTypeSelection; import javax.print.attribute.standard.Fidelity; import javax.print.attribute.standard.JobName; import javax.print.attribute.standard.JobSheets; import javax.print.attribute.standard.Media; import javax.print.attribute.standard.MediaPrintableArea; import javax.print.attribute.standard.MediaSize; import javax.print.attribute.standard.MediaSizeName; import javax.print.attribute.standard.OrientationRequested; import javax.print.attribute.standard.PageRanges; import javax.print.attribute.standard.PrinterState; import javax.print.attribute.standard.PrinterStateReason; import javax.print.attribute.standard.PrinterStateReasons; import javax.print.attribute.standard.PrinterIsAcceptingJobs; import javax.print.attribute.standard.RequestingUserName; import javax.print.attribute.standard.SheetCollate; import javax.print.attribute.standard.Sides; import sun.print.PageableDoc; import sun.print.ServiceDialog; import sun.print.SunPrinterJobService; import sun.print.SunPageSelection; /** * A class which rasterizes a printer job. * * @author Richard Blanchard */ public abstract class RasterPrinterJob extends PrinterJob { /* Class Constants */ /* Printer destination type. */ protected static final int PRINTER = 0; /* File destination type. */ protected static final int FILE = 1; /* Stream destination type. */ protected static final int STREAM = 2; /** * Maximum amount of memory in bytes to use for the * buffered image "band". 4Mb is a compromise between * limiting the number of bands on hi-res printers and * not using too much of the Java heap or causing paging * on systems with little RAM. */ private static final int MAX_BAND_SIZE = (1024 * 1024 * 4); /* Dots Per Inch */ private static final float DPI = 72.0f; /** * Useful mainly for debugging, this system property * can be used to force the printing code to print * using a particular pipeline. The two currently * supported values are FORCE_RASTER and FORCE_PDL. */ private static final String FORCE_PIPE_PROP = "sun.java2d.print.pipeline"; /** * When the system property FORCE_PIPE_PROP has this value * then each page of a print job will be rendered through * the raster pipeline. */ private static final String FORCE_RASTER = "raster"; /** * When the system property FORCE_PIPE_PROP has this value * then each page of a print job will be rendered through * the PDL pipeline. */ private static final String FORCE_PDL = "pdl"; /** * When the system property SHAPE_TEXT_PROP has this value * then text is always rendered as a shape, and no attempt is made * to match the font through GDI */ private static final String SHAPE_TEXT_PROP = "sun.java2d.print.shapetext"; /** * values obtained from System properties in static initialiser block */ public static boolean forcePDL = false; public static boolean forceRaster = false; public static boolean shapeTextProp = false; static { /* The system property FORCE_PIPE_PROP * can be used to force the printing code to * use a particular pipeline. Either the raster * pipeline or the pdl pipeline can be forced. */ String forceStr = (String)java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction(FORCE_PIPE_PROP)); if (forceStr != null) { if (forceStr.equalsIgnoreCase(FORCE_PDL)) { forcePDL = true; } else if (forceStr.equalsIgnoreCase(FORCE_RASTER)) { forceRaster = true; } } String shapeTextStr = (String)java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction(SHAPE_TEXT_PROP)); if (shapeTextStr != null) { shapeTextProp = true; } } /* Instance Variables */ /** * Used to minimise GC & reallocation of band when printing */ private int cachedBandWidth = 0; private int cachedBandHeight = 0; private BufferedImage cachedBand = null; /** * The number of book copies to be printed. */ private int mNumCopies = 1; /** * Collation effects the order of the pages printed * when multiple copies are requested. For two copies * of a three page document the page order is: * mCollate true: 1, 2, 3, 1, 2, 3 * mCollate false: 1, 1, 2, 2, 3, 3 */ private boolean mCollate = false; /** * The zero based indices of the first and last * pages to be printed. If 'mFirstPage' is * UNDEFINED_PAGE_NUM then the first page to * be printed is page 0. If 'mLastPage' is * UNDEFINED_PAGE_NUM then the last page to * be printed is the last one in the book. */ private int mFirstPage = Pageable.UNKNOWN_NUMBER_OF_PAGES; private int mLastPage = Pageable.UNKNOWN_NUMBER_OF_PAGES; /** * The previous print stream Paper * Used to check if the paper size has changed such that the * implementation needs to emit the new paper size information * into the print stream. * Since we do our own rotation, and the margins aren't relevant, * Its strictly the dimensions of the paper that we will check. */ private Paper previousPaper; /** * The document to be printed. It is initialized to an * empty (zero pages) book. */ private Pageable mDocument = new Book(); /** * The name of the job being printed. */ private String mDocName = "Java Printing"; /** * Printing cancellation flags */ private boolean performingPrinting = false; private boolean userCancelled = false; /** * Print to file permission variables. */ private FilePermission printToFilePermission; /** * List of areas & the graphics state for redrawing */ private ArrayList redrawList = new ArrayList(); /* variables representing values extracted from an attribute set. * These take precedence over values set on a printer job */ private int copiesAttr; private String jobNameAttr; private String userNameAttr; private PageRanges pageRangesAttr; protected Sides sidesAttr; protected String destinationAttr; protected boolean noJobSheet = false; protected int mDestType = RasterPrinterJob.FILE; protected String mDestination = ""; protected boolean collateAttReq = false; /** * Device rotation flag, if it support 270, this is set to true; */ protected boolean landscapeRotates270 = false; /** * attributes used by no-args page and print dialog and print method to * communicate state */ protected PrintRequestAttributeSet attributes = null; /** * Class to keep state information for redrawing areas * "region" is an area at as a high a resolution as possible. * The redrawing code needs to look at sx, sy to calculate the scale * to device resolution. */ private class GraphicsState { Rectangle2D region; // Area of page to repaint Shape theClip; // image drawing clip. AffineTransform theTransform; // to transform clip to dev coords. double sx; // X scale from region to device resolution double sy; // Y scale from region to device resolution } /** * Service for this job */ protected PrintService myService; /* Constructors */ public RasterPrinterJob() { } /* Abstract Methods */ /** * Returns the resolution in dots per inch across the width * of the page. */ abstract protected double getXRes(); /** * Returns the resolution in dots per inch down the height * of the page. */ abstract protected double getYRes(); /** * Must be obtained from the current printer. * Value is in device pixels. * Not adjusted for orientation of the paper. */ abstract protected double getPhysicalPrintableX(Paper p); /** * Must be obtained from the current printer. * Value is in device pixels. * Not adjusted for orientation of the paper. */ abstract protected double getPhysicalPrintableY(Paper p); /** * Must be obtained from the current printer. * Value is in device pixels. * Not adjusted for orientation of the paper. */ abstract protected double getPhysicalPrintableWidth(Paper p); /** * Must be obtained from the current printer. * Value is in device pixels. * Not adjusted for orientation of the paper. */ abstract protected double getPhysicalPrintableHeight(Paper p); /** * Must be obtained from the current printer. * Value is in device pixels. * Not adjusted for orientation of the paper. */ abstract protected double getPhysicalPageWidth(Paper p); /** * Must be obtained from the current printer. * Value is in device pixels. * Not adjusted for orientation of the paper. */ abstract protected double getPhysicalPageHeight(Paper p); /** * Begin a new page. */ abstract protected void startPage(PageFormat format, Printable painter, int index, boolean paperChanged) throws PrinterException; /** * End a page. */ abstract protected void endPage(PageFormat format, Printable painter, int index) throws PrinterException; /** * Prints the contents of the array of ints, 'data' * to the current page. The band is placed at the * location (x, y) in device coordinates on the * page. The width and height of the band is * specified by the caller. */ abstract protected void printBand(byte[] data, int x, int y, int width, int height) throws PrinterException; /* Instance Methods */ /** * save graphics state of a PathGraphics for later redrawing * of part of page represented by the region in that state */ public void saveState(AffineTransform at, Shape clip, Rectangle2D region, double sx, double sy) { GraphicsState gstate = new GraphicsState(); gstate.theTransform = at; gstate.theClip = clip; gstate.region = region; gstate.sx = sx; gstate.sy = sy; redrawList.add(gstate); } /* * A convenience method which returns the default service * for 2D <code>PrinterJob</code>s. * May return null if there is no suitable default (although there * may still be 2D services available). * @return default 2D print service, or null. * @since 1.4 */ protected static PrintService lookupDefaultPrintService() { PrintService service = PrintServiceLookup.lookupDefaultPrintService(); /* Pageable implies Printable so checking both isn't strictly needed */ if (service != null && service.isDocFlavorSupported( DocFlavor.SERVICE_FORMATTED.PAGEABLE) && service.isDocFlavorSupported( DocFlavor.SERVICE_FORMATTED.PRINTABLE)) { return service; } else { PrintService []services = PrintServiceLookup.lookupPrintServices( DocFlavor.SERVICE_FORMATTED.PAGEABLE, null); if (services.length > 0) { return services[0]; } } return null; } /** * Returns the service (printer) for this printer job. * Implementations of this class which do not support print services * may return null; * @return the service for this printer job. * */ public PrintService getPrintService() { if (myService == null) { PrintService svc = PrintServiceLookup.lookupDefaultPrintService(); if (svc != null && svc.isDocFlavorSupported( DocFlavor.SERVICE_FORMATTED.PAGEABLE)) { try { setPrintService(svc); myService = svc; } catch (PrinterException e) { } } if (myService == null) { PrintService[] svcs = PrintServiceLookup.lookupPrintServices( DocFlavor.SERVICE_FORMATTED.PAGEABLE, null); if (svcs.length > 0) { try { setPrintService(svcs[0]); myService = svcs[0]; } catch (PrinterException e) { } } } } return myService; } /** * Associate this PrinterJob with a new PrintService. * * Throws <code>PrinterException</code> if the specified service * cannot support the <code>Pageable</code> and * <code>Printable</code> interfaces necessary to support 2D printing. * @param a print service which supports 2D printing. * * @throws PrinterException if the specified service does not support * 2D printing or no longer available. */ public void setPrintService(PrintService service) throws PrinterException { if (service == null) { throw new PrinterException("Service cannot be null"); } else if (!(service instanceof StreamPrintService) && service.getName() == null) { throw new PrinterException("Null PrintService name."); } else { // Check the list of services. This service may have been