End users expect to be able to print to printers attached to local machines or to the network itself. The applets and applications they use may run in concert with a browser or directly on top of an operating system itself. There may be server code somewhere on the network that these apps/applets use (especially thin clients). In all cases, users expect to be able to print from their desktop to any printers on their network.
The Java environment must meet this need by providing a rich set of printing interfaces and functionality, including:
The original JDK 1.0 release did not provide any printing support. The release of the 1.1 version of the Java Developer's Kit in 1997 provided Java developers with a basic framework for printing from applications. JDK 1.1 Core contains facilities for "platform printing": using a printer that is accessible to the client platform. Note that this does not necessarily require that the printer be connected physically to the client machine, but rather that the Java client uses facilities provided by the platform operating system to use a printer. Also note that some Java platforms may have no printer accessible, directly or indirectly.
To print, a client initiates a print job by obtaining a new instance of PrintJob. The PrintJob class will create for you an instance of a concrete subclass of Graphics, which implements all the usual rendering calls for text, graphics, and images. This subclass differs from the normal Graphics subclasses in that rendering is done not on the screen, but on a printer. In practice, the subclass either builds a document file, such as PostScript, and ships it to a printer, or it passes the responsibility on to the operating system, e.g., on Windows 95, the implementation exploits the ability of the underlying window system to divert rendering calls to a printer. You indicate the end of each page by calling dispose() on the Graphics subclass, and obtain a new graphics instance from PrintJob for the next page.
The SDK 1.2 advanced the state of printing with the Java platform: the java.awt.print
package can print all Java 2D graphics or Java AWT graphics, and the interface is extensible enough to allow for the addition of powerful new printing features in the future.
The Java printing system uses a callback model in which the printing system controls when pages are printed; the application provides information about the document to be printed, and the printing system asks the application to render each page as it needs them.
While untraditional, the callback model fits better with the existing AWT component painting model. The printing system might request that a particular page be rendered more than once or request that pages be rendered out of order. The application must be able to generate the proper page image, no matter which page the printing system requests. In this respect, the printing system is similar to the window toolkit, which can request components to repaint at any time, in any order.
The callback printing model is also more flexible than traditional application-driven printing models and supports printing on a wider range of systems and printers. For example, if a printer stacks output pages in reverse order, the printing system can ask the application to generate pages in reverse order so that the final stack is in proper reading order.
For the SDK, version 1.3, the 1.1 (AWT) Java Printing API included two new classes: JobAttributes
and PageAttributes
. The JobAttributes
class controls the properties of a print job, such as destination and number of copies. The PageAttributes
class controls the attributes of a printed page, such as paper size, orientation, and print quality. These new classes are used by the new method getPrintJob(Frame, String, JobAttributes, PageAttributes)
in java.awt.Toolkit
. This method returns a PrintJob
object, which encapsulates the information associated with a printing request.
The JobAttributes
and PageAttributes
classes provide an application with the ability to store particular attributes as instances of these classes, which can be applied to different printing jobs. With the JobAttributes
class, you can specify a cross-platform dialog, which was not available in previous versions of the SDK.
The proposed Unified Printing Model will allow printing on all platforms requiring a Java Print API, including platforms requiring a small footprint, such as a J2ME profile, but will still support the current Java 2 Print API, which allows printing of all Java 2D graphics. This unified Java Print API uses the extendable, industry-standard attribute set specified in the Internet Printing Protocol (IPP) 1.1 from the IETF. The Unified Printing Model also builds on previously-released printing features, such as the ability to specify a cross-platform dialog.
Through a Service Provider Interface, the Java Print Service will enable third parties to install their own print services, such as a JINI print service, which could print different formats, including Postscript, PDF, and SVG, with a specified attribute set, as defined by the IPP.
The Java 2D printing API, introduced in the SDK 1.2, will be integrated with the Java Print Service. As a result, applications that print 2D graphics will be able to :
DocFlavor
and StreamPrinter2D API.New Java Print Service API
The proposed JPS API will be the package javax.print
. Please note that this API is still being developed through the Java Community Process and is subject to change. The main proposed JPS classes are:
Doc
: Specifies the interface for the print data.DocPrintJob
: Initiates printing on the Doc
with the specified attributesDocFlavor
: Specifies the format for the print dataPrintService
: Describes a printers capabilities and creates a DocPrintJob
PrintServiceLookup
: Finds printers capable of printing the specified flavor and supporting the specified attribute set. Third parties can implement this class to plug in their own print services through a Service Provider Interface.
// PrintDoc is an implementation of Doc
Doc psDoc = new PrintDoc("file.ps");
// Gets the format of the document
DocFlavor psFlavor = psDoc.getDocFlavor();
// Creates a new attribute set
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
// Prints 5 copies
aset.add(new Copies(5));
// Specifies the size of the medium
aset.add(MediaSize.A4);
// Prints two-sided
aset.add(Sides.DUPLEX);
// Staples the pages
aset.add( FinishingsBinding STAPLE);
/* Locates printers that can print the specified document format
* with the specified attribute set
*/
PrintService[] services =
PrintServiceLookup.lookupPrintServices(psFlavor, aset);
if (services != null && services.length > 0) {
DocPrintJob job = services[0].createPrintJob();
try {
job.print(psDoc, aset);
}
} catch (PrintException pe) {
}
New Java 2D Printing API
The proposed Java 2D printing API will be added to the java.awt.print
package. Please note that this API is still being developed and is subject to change. The main proposed Java 2D printing classes are:
StreamPrinter2D DocFlavor javax.print DocFlavor PrintServiceLookup javax.print
DocFlavor psFlavor =
new DocFlavor("application/postscript", "java.io.OutputStream");
StreamPrinter2D[] streamPrinter[] =
PrinterServiceLookup.lookupStreamPrinters(psFlavor);
if(streamPrinter != null && streamPrinter.length > 0) {
StreamPrinter2D sprinter = streamPrinter[0];
try {
FileOutputStream fos = new FileOutputStream("out.ps");
PrinterJob pjob =
PrinterJob.getPrinterJob(sprinter, fos);
pjob.setPageable(this);
pjob.print();
fos.close();
} catch (IOException e) {
} catch (PrinterException e) {
}
}
Users who print with the Java platform should find that many of their needs and the goals we have set in the beginning of this paper either have already been met by previous SDK releases or will be met by the new Unified Printing API. To review, we said that the Java environment must provide a rich set of printing functionality, including:
The standard GUI component, or print dialog, was available in the JDK 1.1. With the SDK 1.3, users can specify a cross-platform print dialog. When the SDK 1.4 is available, users will still be able to specify a cross-platform print dialog, but they will also be able to discover and select a printer from their application code, whereas before they could only select a printer with the print dialog.
The third goal is met by the Unified Printing API, which allows third parties to plug in print services through a Service Provider Interface. In addition to print services, third parties can add their own attribute sets because the attributes included with JPS are first-class objects, which can be extended, and are based on the industry-standard attribute names specified in the IPP 1.1.