On GameSpot: Wii Fit tells 10-year-old she's fat

Print on all Java platforms with JPS

Tags: Programming languages, Peter V. Mikhalenko, Java Platform, Java, Print Job, Java Print Service, Java Tips Newsletter

  • Save
  • Print
  • Digg This
  • 2

Takeaway: Java Print Service (JPS) allows you to print even on very size-limited platforms such as J2ME; it also supports standard Java 2D graphics. Learn how to organize printing with this API.

Java Print Service (JPS), introduced in JDK 1.4, is an API intended for printing on all Java platforms. It includes the Java 2 Print API, which was used before the introduction of JPS. This article explains how client and server applications can locate and select printers that have the capabilities specified by the appropriate attributes.

Features

JPS APIs are based on the unified printing model described in JSR 6. These APIs use the extendable, industry standard attribute set specified in the Internet Printing Protocol (IPP) 1.1 from the Internet Engineering Task Force (IETF). JPS allows you to print even on very size-limited platforms such as J2ME; it also supports standard Java 2D graphics.

Get developer tips in your inbox
Delivered each Thursday, our free Java newsletter provides insight and hands-on tips you need to unlock the full potential of this programming language.
Automatically sign up today!

The most important features of JPS are:

  • Printer Discovery: Both the client- and server-side applications can programmatically do Printer Discovery and find suitable printers that can print the Print Job with user-specified attributes. There are a variety of Print Job attributes that you can specify, such as the number of sides (single-sided or double-sided); chromaticity (color or monochrome); media size (A4, legal, letter, etc.); Print Job name (specify a name for any printing job), and so on.
  • Print Job Attributes as Objects: Implementations of standard IPP attributes are included in the JPS API as objects.
  • Print Job Attribute Classes: Applications can extend the attributes included with the JPS API.
  • Service Provider Interface (SPI): Third parties can plug in their own Print Services using the SPIs. Print Service is implemented most effectively and efficiently when you use the vendor provided SPI.

How to organize printing

Printing with the JPS API involves a three-part process of discovery, specification, and printing. An optional fourth part involves notification as a printing task progresses. (All of the classes and interfaces that I cover in this article are in the javax.print package or one of its subpackages.)

The first step to executing a print job is to identify the printer or set of printers you want to print to. Printer objects are called print services, and the identification process is called a lookup. The support class for the lookup task is named PrintServiceLookup. You can use any of these three methods:

  • lookupDefaultPrintService() returns the default print service.
  • lookupPrintServices () returns the set of printers that support printing a specific document type (such as PNG or HTML) with a specific set of attributes (such as two-sided).
  • lookupMultiDocPrintServices () provides support for printing multiple documents at once.

After you've located the print service you want to use, you need to create a print job. (Later on, you'll send output to this job.) You can use the PrintService returned by the lookup to create the job with its createPrintJob() method:

  PrintService printService = 
    PrintServiceLookup.lookupDefaultPrintService();
  DocPrintJob job = printService.createPrintJob();

Once you specify the service, you must specify the format of your print documents. The DocFlavor class is used to identify the Multipurpose Internet Mail Extensions (MIME) type of the object you want to print. The MIME type describes how electronic data should be interpreted. You may have run across MIME types when working with e-mail and attachments, but the MIME specification describes a more general purpose mechanism for identifying data forms.

There are several subclasses of DocFlavor, and they can be broken up into three subsets of MIME types: byte-oriented, character-oriented, and service-oriented. Each flavor type supports its own set of MIME types. These types are defined again as inner classes of DocFlavor subclasses (which are also inner classes, so it's an inner class of an inner class).

  • Byte-oriented flavors include GIF, JPEG, PDF, PNG, POSTSCRIPT, TEXT_HTML_UTF_8, and others.
  • Character-oriented streams can be only one of two formats: TEXT_HTML and TEXT_PLAIN.
  • Service-oriented streams can be PAGEABLE, PRINTABLE, or RENDERABLE_IMAGE.

For example, here is how you would configure the flavor in order to print a PNG picture:

DocFlavor flavor = DocFlavor.INPUT_STREAM.PNG;

You can also specify attributes that describe how you want to print a document. Example attributes include number of copies, which pages to print, and the document image type (for example, landscape vs. portrait). To specify attributes, you need to work with one of two classes:

  • DocAttributeSet specifies the characteristics for a single document.
  • PrintRequestAttributeSet specifies the characteristics of a single print job.

Here is an example of how you can print two copies of an object:

  PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
  pras.add(new Copies(2));

You can have a look at the full list of accessible attributes in the javax.print.attribute package.

The Doc interface provides the data to the print job. The implementer of the interface is the SimpleDoc class. With a single constructor, you provide the content as the first parameter, the flavor as the second parameter, and the attributes as the third parameter. The content is accepted as Object, thus you have to supplement an appropriate object type in actual data. If you specify a flavor of DocFlavor.INPUT_STREAM, then the data would be identified by its InputStream. If your flavor is DocFlavor.BYTE_ARRAY, then the data would be a byte array (byte []).

To print a PNG picture from a file, use the following code:

  DocFlavor flavor = DocFlavor.INPUT_STREAM.PNG;
  String filename = ...;
  FileInputStream fis = new FileInputSteam(filename);
  DocAttributeSet das = new HashDocAttributeSet();
  Doc doc = new SimpleDoc(fis, flavor, das);

You can finally print by using the print() method of the DocPrintJob object, which I already retrieved from the PrintService, as shown above:

job. print(doc, pras);

By calling print(), you trigger the mechanism to send your content to the print service in a separate thread.

For additional information about printing on the J2SE platform, visit the Sun Developer Network.

Peter V. Mikhalenko is a Sun certified professional who works for Deutsche Bank as a business consultant.

  • Save
  • Print
  • Digg This
  • 2

Print/View all Posts Comments on this article

mobile supports this specificationfaisalahmed91@...  | 11/23/07
RE: Print on all Java platforms with JPSmritunjaygiri@...  | 06/19/08

What do you think?


The Green Enterprise

advertisement
Click Here