jobAttributes.setDefaultSelection(DefaultSelectionType.RANGE); } else if (sel == SunPageSelection.SELECTION) { jobAttributes.setDefaultSelection(DefaultSelectionType.SELECTION); } else { jobAttributes.setDefaultSelection(DefaultSelectionType.ALL); } Destination dest = (Destination)attributes.get(Destination.class); if (dest != null) { jobAttributes.setDestination(DestinationType.FILE); jobAttributes.setFileName(dest.getURI().getPath()); } else { jobAttributes.setDestination(DestinationType.PRINTER); } PrintService serv = printerJob.getPrintService(); if (serv != null) { jobAttributes.setPrinter(serv.getName()); } PageRanges range = (PageRanges)attributes.get(PageRanges.class); int[][] members = range.getMembers(); jobAttributes.setPageRanges(members); SheetCollate collation = (SheetCollate)attributes.get(SheetCollate.class); if (collation == SheetCollate.COLLATED) { jobAttributes.setMultipleDocumentHandling( MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_COLLATED_COPIES); } else { jobAttributes.setMultipleDocumentHandling( MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES); } Sides sides = (Sides)attributes.get(Sides.class); if (sides == Sides.TWO_SIDED_LONG_EDGE) { jobAttributes.setSides(SidesType.TWO_SIDED_LONG_EDGE); } else if (sides == Sides.TWO_SIDED_SHORT_EDGE) { jobAttributes.setSides(SidesType.TWO_SIDED_SHORT_EDGE); } else { jobAttributes.setSides(SidesType.ONE_SIDED); } // PageAttributes Chromaticity color = (Chromaticity)attributes.get(Chromaticity.class); if (color == Chromaticity.COLOR) { pageAttributes.setColor(ColorType.COLOR); } else { pageAttributes.setColor(ColorType.MONOCHROME); } OrientationRequested orient = (OrientationRequested)attributes.get(OrientationRequested.class); if (orient == OrientationRequested.LANDSCAPE) { pageAttributes.setOrientationRequested( OrientationRequestedType.LANDSCAPE); } else { pageAttributes.setOrientationRequested( OrientationRequestedType.PORTRAIT); } PrintQuality qual = (PrintQuality)attributes.get(PrintQuality.class); if (qual == PrintQuality.DRAFT) { pageAttributes.setPrintQuality(PrintQualityType.DRAFT); } else if (qual == PrintQuality.HIGH) { pageAttributes.setPrintQuality(PrintQualityType.HIGH); } else { // NORMAL pageAttributes.setPrintQuality(PrintQualityType.NORMAL); } Media msn = (Media)attributes.get(Media.class); if (msn != null && msn instanceof MediaSizeName) { MediaType mType = unMapMedia((MediaSizeName)msn); if (mType != null) { pageAttributes.setMedia(mType); } } debugPrintAttributes(false, false); } private void debugPrintAttributes(boolean ja, boolean pa ) { if (ja) { System.out.println("new Attributes\ncopies = "+ jobAttributes.getCopies()+ "\nselection = "+ jobAttributes.getDefaultSelection()+ "\ndest "+jobAttributes.getDestination()+ "\nfile "+jobAttributes.getFileName()+ "\nfromPage "+jobAttributes.getFromPage()+ "\ntoPage "+jobAttributes.getToPage()+ "\ncollation "+ jobAttributes.getMultipleDocumentHandling()+ "\nPrinter "+jobAttributes.getPrinter()+ "\nSides2 "+jobAttributes.getSides() ); } if (pa) { System.out.println("new Attributes\ncolor = "+ pageAttributes.getColor()+ "\norientation = "+ pageAttributes.getOrientationRequested()+ "\nquality "+pageAttributes.getPrintQuality()+ "\nMedia2 "+pageAttributes.getMedia() ); } } /* From JobAttributes we will copy job name and duplex printing * and destination. * The majority of the rest of the attributes are reflected * attributes. * * From PageAttributes we copy color, media size, orientation, * origin type, resolution and print quality. * We use the media, orientation in creating the page format, and * the origin type to set its imageable area. * * REMIND: Interpretation of resolution, additional media sizes. */ private void copyAttributes(PrintService printServ) { attributes = new HashPrintRequestAttributeSet(); attributes.add(new JobName(docTitle, null)); PrintService pServ = printServ; String printerName = jobAttributes.getPrinter(); if (printerName != null && printerName != "" && !printerName.equals(pServ.getName())) { // Search for the given printerName in the list of PrintServices PrintService []services = PrinterJob.lookupPrintServices(); try { for (int i=0; i<services.length; i++) { if (printerName.equals(services[i].getName())) { printerJob.setPrintService(services[i]); pServ = services[i]; break; } } } catch (PrinterException pe) { } } DestinationType dest = jobAttributes.getDestination(); if (dest == DestinationType.FILE && pServ.isAttributeCategorySupported(Destination.class)) { String fileName = jobAttributes.getFileName(); Destination defaultDest; if (fileName == null && (defaultDest = (Destination)pServ. getDefaultAttributeValue(Destination.class)) != null) { attributes.add(defaultDest); } else { URI uri = null; try { if (fileName != null) { if (fileName.equals("")) { fileName = "."; } } else { // defaultDest should not be null. The following code // is only added to safeguard against a possible // buggy implementation of a PrintService having a // null default Destination. fileName = "out.prn"; } uri = (new File(fileName)).toURI(); } catch (SecurityException se) { try { // '\\' file separator is illegal character in opaque // part and causes URISyntaxException, so we replace // it with '/' fileName = fileName.replace('\\', '/'); uri = new URI("file:"+fileName); } catch (URISyntaxException e) { } } if (uri != null) { attributes.add(new Destination(uri)); } } } attributes.add(new SunMinMaxPage(jobAttributes.getMinPage(), jobAttributes.getMaxPage())); SidesType sType = jobAttributes.getSides(); if (sType == SidesType.TWO_SIDED_LONG_EDGE) { attributes.add(Sides.TWO_SIDED_LONG_EDGE); } else if (sType == SidesType.TWO_SIDED_SHORT_EDGE) { attributes.add(Sides.TWO_SIDED_SHORT_EDGE); } else if (sType == SidesType.ONE_SIDED) { attributes.add(Sides.ONE_SIDED); } MultipleDocumentHandlingType hType = jobAttributes.getMultipleDocumentHandling(); if (hType == MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_COLLATED_COPIES) { attributes.add(SheetCollate.COLLATED); } else { attributes.add(SheetCollate.UNCOLLATED); } attributes.add(new Copies(jobAttributes.getCopies())); attributes.add(new PageRanges(jobAttributes.getFromPage(), jobAttributes.getToPage())); if (pageAttributes.getColor() == ColorType.COLOR) { attributes.add(Chromaticity.COLOR); } else { attributes.add(Chromaticity.MONOCHROME); } pageFormat = printerJob.defaultPage(); if (pageAttributes.getOrientationRequested() == OrientationRequestedType.LANDSCAPE) { pageFormat.setOrientation(PageFormat.LANDSCAPE); attributes.add(OrientationRequested.LANDSCAPE); } else { pageFormat.setOrientation(PageFormat.PORTRAIT); attributes.add(OrientationRequested.PORTRAIT); } MediaType media = pageAttributes.getMedia(); MediaSizeName msn = mapMedia(media); if (msn != null) { attributes.add(msn); } PrintQualityType qType = pageAttributes.getPrintQuality(); if (qType == PrintQualityType.DRAFT) { attributes.add(PrintQuality.DRAFT); } else if (qType == PrintQualityType.NORMAL) { attributes.add(PrintQuality.NORMAL); } else if (qType == PrintQualityType.HIGH) { attributes.add(PrintQuality.HIGH); } } /** * Gets a Graphics object that will draw to the next page. * The page is sent to the printer when the graphics * object is disposed. This graphics object will also implement * the PrintGraphics interface. * @see PrintGraphics */ public Graphics getGraphics() { Graphics printGraphics = null; synchronized (this) { ++pageIndex; // Thread should not be created after end has been called. // One way to detect this is if any of the graphics queue // has been closed. if (pageIndex == 0 && !graphicsToBeDrawn.isClosed()) { /* We start a thread on which the PrinterJob will run. * The PrinterJob will ask for pages on that thread * and will use a message queue to fulfill the application's * requests for a Graphics on the application's * thread. */ startPrinterJobThread(); } notify(); } /* If the application has already been handed back * a graphics then we need to put that graphics into * the drawn queue so that the PrinterJob thread can * return to the print system. */ if (currentGraphics != null) { graphicsDrawn.append(currentGraphics); currentGraphics = null; } /* We'll block here until a new graphics becomes * available. */ currentGraphics = graphicsToBeDrawn.pop(); if (currentGraphics instanceof PeekGraphics) { ( (PeekGraphics) currentGraphics).setAWTDrawingOnly(); graphicsDrawn.append(currentGraphics); currentGraphics = graphicsToBeDrawn.pop(); } if (currentGraphics != null) { /* In the PrintJob API, the origin is at the upper- * left of the imageable area when using the new "printable" * origin attribute, otherwise its the physical origin (for * backwards compatibility. We emulate this by createing * a PageFormat which matches and then performing the * translate to the origin. This is a no-op if physical * origin is specified. */ currentGraphics.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); /* Scale to accomodate AWT's notion of printer resolution */ double awtScale = 72.0/getPageResolutionInternal(); currentGraphics.scale(awtScale, awtScale); /* The caller wants a Graphics instance but we do * not want them to make 2D calls. We can't hand * back a Graphics2D. The returned Graphics also * needs to implement PrintGraphics, so we wrap * the Graphics2D instance. The PrintJob API has * the application dispose of the Graphics so * we create a copy of the one returned by PrinterJob. */ printGraphics = new ProxyPrintGraphics(currentGraphics.create(), this); } return printGraphics; } /** * Returns the dimensions of the page in pixels. * The resolution of the page is chosen so that it * is similar to the screen resolution. * Except (since 1.3) when the application specifies a resolution. * In that case it it scaled accordingly. */ public Dimension getPageDimension() { double wid, hgt, scale; if (pageAttributes != null && pageAttributes.getOrigin()==OriginType.PRINTABLE) { wid = pageFormat.getImageableWidth(); hgt = pageFormat.getImageableHeight(); } else { wid = pageFormat.getWidth(); hgt = pageFormat.getHeight(); } scale = getPageResolutionInternal() / 72.0; return new Dimension((int)(wid * scale), (int)(hgt * scale)); } private double getPageResolutionInternal() { if (pageAttributes != null) { int []res = pageAttributes.getPrinterResolution(); if (res[2] == 3) { return res[0]; } else /* if (res[2] == 4) */ { return (res[0] * 2.54); } } else { return 72.0; } } /** * Returns the resolution of the page in pixels per inch. * Note that this doesn't have to correspond to the physical * resolution of the printer. */ public int getPageResolution() { return (int)getPageResolutionInternal(); } /** * Returns true if the last page will be printed first. */ public boolean lastPageFirst() { return false; } /** * Ends the print job and does any necessary cleanup. */ public synchronized void end() { /* Prevent the PrinterJob thread from appending any more * graphics to the to-be-drawn queue */ graphicsToBeDrawn.close(); /* If we have a currentGraphics it was the last one returned to the * PrintJob client. Append it to the drawn queue so that print() * will return allowing the page to be flushed. * This really ought to happen in dispose() but for whatever reason * that isn't how the old PrintJob worked even though its spec * said dispose() flushed the page. */ if (currentGraphics != null) { graphicsDrawn.append(currentGraphics); } graphicsDrawn.closeWhenEmpty(); /* Wait for the PrinterJob.print() thread to terminate, ensuring * that RasterPrinterJob has made its end doc call, and resources * are released, files closed etc. */ if( printerJobThread != null && printerJobThread.isAlive() ){ try { printerJobThread.join(); } catch (InterruptedException e) { } } } /** * Ends this print job once it is no longer referenced. * @see #end */ public void finalize() { end(); } /** * Prints the page at the specified index into the specified * {@link Graphics} context in the specified * format. A <code>PrinterJob</code> calls the * <code>Printable</code> interface to request that a page be * rendered into the context specified by * <code>graphics</code>. The format of the page to be drawn is * specified by <code>pageFormat</code>. The zero based index * of the requested page is specified by <code>pageIndex</code>. * If the requested page does not exist then this method returns * NO_SUCH_PAGE; otherwise PAGE_EXISTS is returned. * The <code>Graphics</code> class or subclass implements the * {@link PrinterGraphics} interface to provide additional * information. If the <code>Printable</code> object * aborts the print job then it throws a {@link PrinterException}. * @param graphics the context into which the page is drawn * @param pageFormat the size and orientation of the page being drawn * @param pageIndex the zero based index of the page to be drawn * @return PAGE_EXISTS if the page is rendered successfully * or NO_SUCH_PAGE if <code>pageIndex</code> specifies a * non-existent page. * @exception java.awt.print.PrinterException * thrown when the print job is terminated. */ public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException { int result; /* This method will be called by the PrinterJob on a thread other * that the application's thread. We hold on to the graphics * until we can rendevous with the application's thread and * hand over the graphics. The application then does all the * drawing. When the application is done drawing we rendevous * again with the PrinterJob thread and release the Graphics * so that it knows we are done. */ /* Add the graphics to the message queue of graphics to * be rendered. This is really a one slot queue. The * application's thread will come along and remove the * graphics from the queue when the app asks for a graphics. */ graphicsToBeDrawn.append( (Graphics2D) graphics); /* We now wait for the app's thread to finish drawing on * the Graphics. This thread will sleep until the application * release the graphics by placing it in the graphics drawn * message queue. If the application signals that it is * finished drawing the entire document then we'll get null * returned when we try and pop a finished graphic. */ if (graphicsDrawn.pop() != null) { result = PAGE_EXISTS; } else { result = NO_SUCH_PAGE; } return result; } private void startPrinterJobThread() { printerJobThread = new Thread(this, "printerJobThread"); printerJobThread.start(); } public void run() { try { printerJob.print(attributes); } catch (PrinterException e) { //REMIND: need to store this away and not rethrow it.Lines 501–1000 of 1257. Previous lines Load more
jobAttributes.setDefaultSelection(DefaultSelectionType.RANGE); } else if (sel == SunPageSelection.SELECTION) { jobAttributes.setDefaultSelection(DefaultSelectionType.SELECTION); } else { jobAttributes.setDefaultSelection(DefaultSelectionType.ALL); } Destination dest = (Destination)attributes.get(Destination.class); if (dest != null) { jobAttributes.setDestination(DestinationType.FILE); jobAttributes.setFileName(dest.getURI().getPath()); } else { jobAttributes.setDestination(DestinationType.PRINTER); } PrintService serv = printerJob.getPrintService(); if (serv != null) { jobAttributes.setPrinter(serv.getName()); } PageRanges range = (PageRanges)attributes.get(PageRanges.class); int[][] members = range.getMembers(); jobAttributes.setPageRanges(members); SheetCollate collation = (SheetCollate)attributes.get(SheetCollate.class); if (collation == SheetCollate.COLLATED) { jobAttributes.setMultipleDocumentHandling( MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_COLLATED_COPIES); } else { jobAttributes.setMultipleDocumentHandling( MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES); } Sides sides = (Sides)attributes.get(Sides.class); if (sides == Sides.TWO_SIDED_LONG_EDGE) { jobAttributes.setSides(SidesType.TWO_SIDED_LONG_EDGE); } else if (sides == Sides.TWO_SIDED_SHORT_EDGE) { jobAttributes.setSides(SidesType.TWO_SIDED_SHORT_EDGE); } else { jobAttributes.setSides(SidesType.ONE_SIDED); } // PageAttributes Chromaticity color = (Chromaticity)attributes.get(Chromaticity.class); if (color == Chromaticity.COLOR) { pageAttributes.setColor(ColorType.COLOR); } else { pageAttributes.setColor(ColorType.MONOCHROME); } OrientationRequested orient = (OrientationRequested)attributes.get(OrientationRequested.class); if (orient == OrientationRequested.LANDSCAPE) { pageAttributes.setOrientationRequested( OrientationRequestedType.LANDSCAPE); } else { pageAttributes.setOrientationRequested( OrientationRequestedType.PORTRAIT); } PrintQuality qual = (PrintQuality)attributes.get(PrintQuality.class); if (qual == PrintQuality.DRAFT) { pageAttributes.setPrintQuality(PrintQualityType.DRAFT); } else if (qual == PrintQuality.HIGH) { pageAttributes.setPrintQuality(PrintQualityType.HIGH); } else { // NORMAL pageAttributes.setPrintQuality(PrintQualityType.NORMAL); } Media msn = (Media)attributes.get(Media.class); if (msn != null && msn instanceof MediaSizeName) { MediaType mType = unMapMedia((MediaSizeName)msn); if (mType != null) { pageAttributes.setMedia(mType); } } debugPrintAttributes(false, false); } private void debugPrintAttributes(boolean ja, boolean pa ) { if (ja) { System.out.println("new Attributes\ncopies = "+ jobAttributes.getCopies()+ "\nselection = "+ jobAttributes.getDefaultSelection()+ "\ndest "+jobAttributes.getDestination()+ "\nfile "+jobAttributes.getFileName()+ "\nfromPage "+jobAttributes.getFromPage()+ "\ntoPage "+jobAttributes.getToPage()+ "\ncollation "+ jobAttributes.getMultipleDocumentHandling()+ "\nPrinter "+jobAttributes.getPrinter()+ "\nSides2 "+jobAttributes.getSides() ); } if (pa) { System.out.println("new Attributes\ncolor = "+ pageAttributes.getColor()+ "\norientation = "+ pageAttributes.getOrientationRequested()+ "\nquality "+pageAttributes.getPrintQuality()+ "\nMedia2 "+pageAttributes.getMedia() ); } } /* From JobAttributes we will copy job name and duplex printing * and destination. * The majority of the rest of the attributes are reflected * attributes. * * From PageAttributes we copy color, media size, orientation, * origin type, resolution and print quality. * We use the media, orientation in creating the page format, and * the origin type to set its imageable area. * * REMIND: Interpretation of resolution, additional media sizes. */ private void copyAttributes(PrintService printServ) { attributes = new HashPrintRequestAttributeSet(); attributes.add(new JobName(docTitle, null)); PrintService pServ = printServ; String printerName = jobAttributes.getPrinter(); if (printerName != null && printerName != "" && !printerName.equals(pServ.getName())) { // Search for the given printerName in the list of PrintServices PrintService []services = PrinterJob.lookupPrintServices(); try { for (int i=0; i<services.length; i++) { if (printerName.equals(services[i].getName())) { printerJob.setPrintService(services[i]); pServ = services[i]; break; } } } catch (PrinterException pe) { } } DestinationType dest = jobAttributes.getDestination(); if (dest == DestinationType.FILE && pServ.isAttributeCategorySupported(Destination.class)) { String fileName = jobAttributes.getFileName(); Destination defaultDest; if (fileName == null && (defaultDest = (Destination)pServ. getDefaultAttributeValue(Destination.class)) != null) { attributes.add(defaultDest); } else { URI uri = null; try { if (fileName != null) { if (fileName.equals("")) { fileName = "."; } } else { // defaultDest should not be null. The following code // is only added to safeguard against a possible // buggy implementation of a PrintService having a // null default Destination. fileName = "out.prn"; } uri = (new File(fileName)).toURI(); } catch (SecurityException se) { try { // '\\' file separator is illegal character in opaque // part and causes URISyntaxException, so we replace // it with '/' fileName = fileName.replace('\\', '/'); uri = new URI("file:"+fileName); } catch (URISyntaxException e) { } } if (uri != null) { attributes.add(new Destination(uri)); } } } attributes.add(new SunMinMaxPage(jobAttributes.getMinPage(), jobAttributes.getMaxPage())); SidesType sType = jobAttributes.getSides(); if (sType == SidesType.TWO_SIDED_LONG_EDGE) { attributes.add(Sides.TWO_SIDED_LONG_EDGE); } else if (sType == SidesType.TWO_SIDED_SHORT_EDGE) { attributes.add(Sides.TWO_SIDED_SHORT_EDGE); } else if (sType == SidesType.ONE_SIDED) { attributes.add(Sides.ONE_SIDED); } MultipleDocumentHandlingType hType = jobAttributes.getMultipleDocumentHandling(); if (hType == MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_COLLATED_COPIES) { attributes.add(SheetCollate.COLLATED); } else { attributes.add(SheetCollate.UNCOLLATED); } attributes.add(new Copies(jobAttributes.getCopies())); attributes.add(new PageRanges(jobAttributes.getFromPage(), jobAttributes.getToPage())); if (pageAttributes.getColor() == ColorType.COLOR) { attributes.add(Chromaticity.COLOR); } else { attributes.add(Chromaticity.MONOCHROME); } pageFormat = printerJob.defaultPage(); if (pageAttributes.getOrientationRequested() == OrientationRequestedType.LANDSCAPE) { pageFormat.setOrientation(PageFormat.LANDSCAPE); attributes.add(OrientationRequested.LANDSCAPE); } else { pageFormat.setOrientation(PageFormat.PORTRAIT); attributes.add(OrientationRequested.PORTRAIT); } MediaType media = pageAttributes.getMedia(); MediaSizeName msn = mapMedia(media); if (msn != null) { attributes.add(msn); } PrintQualityType qType = pageAttributes.getPrintQuality(); if (qType == PrintQualityType.DRAFT) { attributes.add(PrintQuality.DRAFT); } else if (qType == PrintQualityType.NORMAL) { attributes.add(PrintQuality.NORMAL); } else if (qType == PrintQualityType.HIGH) { attributes.add(PrintQuality.HIGH); } } /** * Gets a Graphics object that will draw to the next page. * The page is sent to the printer when the graphics * object is disposed. This graphics object will also implement * the PrintGraphics interface. * @see PrintGraphics */ public Graphics getGraphics() { Graphics printGraphics = null; synchronized (this) { ++pageIndex; // Thread should not be created after end has been called. // One way to detect this is if any of the graphics queue // has been closed. if (pageIndex == 0 && !graphicsToBeDrawn.isClosed()) { /* We start a thread on which the PrinterJob will run. * The PrinterJob will ask for pages on that thread * and will use a message queue to fulfill the application's * requests for a Graphics on the application's * thread. */ startPrinterJobThread(); } notify(); } /* If the application has already been handed back * a graphics then we need to put that graphics into * the drawn queue so that the PrinterJob thread can * return to the print system. */ if (currentGraphics != null) { graphicsDrawn.append(currentGraphics); currentGraphics = null; } /* We'll block here until a new graphics becomes * available. */ currentGraphics = graphicsToBeDrawn.pop(); if (currentGraphics instanceof PeekGraphics) { ( (PeekGraphics) currentGraphics).setAWTDrawingOnly(); graphicsDrawn.append(currentGraphics); currentGraphics = graphicsToBeDrawn.pop(); } if (currentGraphics != null) { /* In the PrintJob API, the origin is at the upper- * left of the imageable area when using the new "printable" * origin attribute, otherwise its the physical origin (for * backwards compatibility. We emulate this by createing * a PageFormat which matches and then performing the * translate to the origin. This is a no-op if physical * origin is specified. */ currentGraphics.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); /* Scale to accomodate AWT's notion of printer resolution */ double awtScale = 72.0/getPageResolutionInternal(); currentGraphics.scale(awtScale, awtScale); /* The caller wants a Graphics instance but we do * not want them to make 2D calls. We can't hand * back a Graphics2D. The returned Graphics also * needs to implement PrintGraphics, so we wrap * the Graphics2D instance. The PrintJob API has * the application dispose of the Graphics so * we create a copy of the one returned by PrinterJob. */ printGraphics = new ProxyPrintGraphics(currentGraphics.create(), this); } return printGraphics; } /** * Returns the dimensions of the page in pixels. * The resolution of the page is chosen so that it * is similar to the screen resolution. * Except (since 1.3) when the application specifies a resolution. * In that case it it scaled accordingly. */ public Dimension getPageDimension() { double wid, hgt, scale; if (pageAttributes != null && pageAttributes.getOrigin()==OriginType.PRINTABLE) { wid = pageFormat.getImageableWidth(); hgt = pageFormat.getImageableHeight(); } else { wid = pageFormat.getWidth(); hgt = pageFormat.getHeight(); } scale = getPageResolutionInternal() / 72.0; return new Dimension((int)(wid * scale), (int)(hgt * scale)); } private double getPageResolutionInternal() { if (pageAttributes != null) { int []res = pageAttributes.getPrinterResolution(); if (res[2] == 3) { return res[0]; } else /* if (res[2] == 4) */ { return (res[0] * 2.54); } } else { return 72.0; } } /** * Returns the resolution of the page in pixels per inch. * Note that this doesn't have to correspond to the physical * resolution of the printer. */ public int getPageResolution() { return (int)getPageResolutionInternal(); } /** * Returns true if the last page will be printed first. */ public boolean lastPageFirst() { return false; } /** * Ends the print job and does any necessary cleanup. */ public synchronized void end() { /* Prevent the PrinterJob thread from appending any more * graphics to the to-be-drawn queue */ graphicsToBeDrawn.close(); /* If we have a currentGraphics it was the last one returned to the * PrintJob client. Append it to the drawn queue so that print() * will return allowing the page to be flushed. * This really ought to happen in dispose() but for whatever reason * that isn't how the old PrintJob worked even though its spec * said dispose() flushed the page. */ if (currentGraphics != null) { graphicsDrawn.append(currentGraphics); } graphicsDrawn.closeWhenEmpty(); /* Wait for the PrinterJob.print() thread to terminate, ensuring * that RasterPrinterJob has made its end doc call, and resources * are released, files closed etc. */ if( printerJobThread != null && printerJobThread.isAlive() ){ try { printerJobThread.join(); } catch (InterruptedException e) { } } } /** * Ends this print job once it is no longer referenced. * @see #end */ public void finalize() { end(); } /** * Prints the page at the specified index into the specified * {@link Graphics} context in the specified * format. A <code>PrinterJob</code> calls the * <code>Printable</code> interface to request that a page be * rendered into the context specified by * <code>graphics</code>. The format of the page to be drawn is * specified by <code>pageFormat</code>. The zero based index * of the requested page is specified by <code>pageIndex</code>. * If the requested page does not exist then this method returns * NO_SUCH_PAGE; otherwise PAGE_EXISTS is returned. * The <code>Graphics</code> class or subclass implements the * {@link PrinterGraphics} interface to provide additional * information. If the <code>Printable</code> object * aborts the print job then it throws a {@link PrinterException}. * @param graphics the context into which the page is drawn * @param pageFormat the size and orientation of the page being drawn * @param pageIndex the zero based index of the page to be drawn * @return PAGE_EXISTS if the page is rendered successfully * or NO_SUCH_PAGE if <code>pageIndex</code> specifies a * non-existent page. * @exception java.awt.print.PrinterException * thrown when the print job is terminated. */ public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException { int result; /* This method will be called by the PrinterJob on a thread other * that the application's thread. We hold on to the graphics * until we can rendevous with the application's thread and * hand over the graphics. The application then does all the * drawing. When the application is done drawing we rendevous * again with the PrinterJob thread and release the Graphics * so that it knows we are done. */ /* Add the graphics to the message queue of graphics to * be rendered. This is really a one slot queue. The * application's thread will come along and remove the * graphics from the queue when the app asks for a graphics. */ graphicsToBeDrawn.append( (Graphics2D) graphics); /* We now wait for the app's thread to finish drawing on * the Graphics. This thread will sleep until the application * release the graphics by placing it in the graphics drawn * message queue. If the application signals that it is * finished drawing the entire document then we'll get null * returned when we try and pop a finished graphic. */ if (graphicsDrawn.pop() != null) { result = PAGE_EXISTS; } else { result = NO_SUCH_PAGE; } return result; } private void startPrinterJobThread() { printerJobThread = new Thread(this, "printerJobThread"); printerJobThread.start(); } public void run() { try { printerJob.print(attributes); } catch (PrinterException e) { //REMIND: need to store this away and not rethrow it.