Home : FAQ : Java Printing API


Java™ 2 Environment Printing API

By Sudhir Ancha

   What is this model?
      Printing was not well supported before Java 2 (Java Development Kit 1.2). The new model introduced in Java 2 is simple and at the same time powerful. Here are the key aspects of this model:

* Printing is performed on a page by page process, even if only one page is to be printed.
* The printing is managed by a single process, which your code kick starts.
* That process passes one blank page at a time to a separate object that fleshes out the page.
* The completed page is sent to the printer by the print manager process.
* This manager stops printing when a page is not fleshed out, or if the print run is cancelled.

The sample code page contains a diagram that graphically illustrates the flow of data and control outlined above. But we will amplify on each element in the paragraphs below.

   Creating the print manager process : a PrinterJob object
      Unlike in many Java packages, a PrinterJob object is not created with a new clause. Instead, the PrinterJob class contains a static method that you must use to create an instance of the class :

PrinterJob job = PrinterJob.getPrinterJob();

This "job" is not ready to do any work until it can use the services of another object that will format the pages. The print job manages the pages; a separate object formats them.

   Establishing a page formatting object
      The role of this object is to format a blank page passed to it by the print job. It simply formats the page, and returns a status code indicating if it was successful. The print job will call this object once (or more) for each page to be printed.

So who controls the number of pages to be printed? A good question. The job does not know about the page contents. It simply asks the page formatter to format them. Neither does it normally know how many pages there are to print (this is not always true - the user can set the range in the print options dialog - see further on). Although the page formatter is only called one page at a time, it is its responsibility to know both what to put on each page, and how many pages to print.

Before going any further, lets us look at a very simple page formatter object class. It will print the page number 1 on the one and only page:

class PrintObject implements Printable
{
  public int print (Graphics g, PageFormat f, int pageIndex)
  {
    if (pageIndex == 0)
    {
      g.drawString("1", 100,100); // Draw the letter 1 at pixel coordinates (100,100)
      return PAGE_EXISTS;
    }
  else return NO_SUCH_PAGE;
  }
}

There are a number of things to note about this class. It implements the Printable interface, and the one and only method (print) within it. This method is how the job interfaces with this object to format a page. This PrintObject class does not actually do any printing within this method. It merely fills the page for the print job to print.

It checks the page index being passed. This starts at 0 - for us, this is page 1. We check this, format the page, and return PAGE_EXISTS so that the job knows it can print it. When the job passes index 1, we reject it with a NO_SUCH_PAGE response. This tells the job to stop printing. Do not worry about the PageFormat parameter at the moment.

   Telling the job about this page formatter
      Now we need to pass an instance of this class to the job so that it can actually call it. We create a PrintObject object and then pass it in the setPrintable method. Normally, we can do this in one statement:

job.setPrintable(new PrintObject());
 
   Setting the page printing options
      Before we actualy do any printing, it is conventional to display a print options dialog, to allow the user to select page format and ink details and so on. This is done by a second method of the job:

job.printDialog();

This keeps things wonderfully simple for the coder. Not only is a full print dialog created and displayed, but the options selected are stored neatly within the job object. This is sensible, as the job manages the print process. It takes formatted pages from the page formatter object, and passes the page and options to the printer via the printer driver. (A print driver is a piece of system software that translates this information into print codes that the printer you have understands).

The print dialog returns true if the user presses OK on the dialog panel, or false if Cancel is pressed.

   Finally, doing some printing!
      If the print dialog returns true, then we are ready to print. All we do is kick start the job by calling its print() method. This takes no parameters, and simply gets the job to call the page formatter for each page in turn until NO_SUCH_PAGE is returned. Control is then passed back to your code that called print(), and the printing continues in parallel, having been furnished with all pages for printing.

During the building of the pages, the page formatter is called. It builds each page on request from the job. In our sample, this was easy. In reality, this may not be trivial, especialy because you have no control over the sequence with which the job requests pages for printing. This is covered in the next page of this article.

The sample code page contains a diagram and code for this example.


Home : FAQ : Java Printing API

 

Copyright© 1998-2004 All Rights Reserved. No portion of this site may be reproduced or redistributed without prior written permission from VistaEdge Technologies

All registered trademarks appearing on this site are the property of their respective owners. Java is a trademark or registered trademark of Sun Microsystems, Inc. in the United States and other countries. This site is not connected to Sun Microsystems, Inc. and is not sponsored by Sun Microsystems, Inc.