CONTENTS | PREV | NEXT Java 2D API


7.3 Printing with Printables

To provide basic printing support:

  1. Implement the Printable interface to provide a page painter that can render each page to be printed.
  2. Create a PrinterJob.
  3. Call setPrintable to tell the PrinterJob how to print your document.
  4. Call print on the PrinterJob object to start the job.
In the following example, a Printable job is used to print five pages, each of which displays a green page number. Job control is managed in the main method, which obtains and controls the PrinterJob. Rendering is performed in the page painter's print method.

import java.awt.*; import java.awt.print.*;
public class SimplePrint implements Printable 
{   

  private static Font fnt = new Font("Helvetica",Font.PLAIN,24);


  public static void main(String[] args) 
  {     
    // Get a PrinterJob     
    PrinterJob job = PrinterJob.getPrinterJob();     
    // Specify the Printable is an instance of SimplePrint
    job.setPrintable(new SimplePrint());     
    // Put up the dialog box     
    if (job.printDialog()) 
    { 	
      // Print the job if the user didn't cancel printing 
      try { job.print(); }
      catch (Exception e)
        { /* handle exception */ }
    }     
    System.exit(0);   
  }


  public int print(Graphics g, PageFormat pf, int pageIndex)
  throws PrinterException 
  {     
    // pageIndex 0 to 4 corresponds to page numbers 1 to 5.
    if (pageIndex >= 5) return Printable.NO_SUCH_PAGE;   
    g.setFont(fnt);     
    g.setColor(Color.green);     
    g.drawString("Page " + (pageIndex+1), 100, 100);     
    return Printable.PAGE_EXISTS;   
  } 
}

7.3.1 Using Graphics2D for Rendering

You can invoke Graphics2D functions in you page painter's print method by first casting the Graphics context to a Graphics2D.

In the following example, the page numbers are rendered using a red-green gradient. To do this, a GradientPaint is set in the Graphics2D context.

import java.awt.*; import java.awt.print.*;
public class SimplePrint2D implements Printable 
{   
  private static Font fnt = new Font("Helvetica",Font.PLAIN,24);

  private Paint pnt = new GradientPaint(100f, 100f, Color.red, 	                                      136f, 100f, Color.green, true);

  public static void main(String[] args) 
  {     
    // Get a PrinterJob     
    PrinterJob job = PrinterJob.getPrinterJob();     
    // Specify the Printable is an instance of SimplePrint2D
    job.setPrintable(new SimplePrint2D());     
    // Put up the dialog box     
    if (job.printDialog()) 
    { 	
      // Print the job if the user didn't cancel printing 
      try { job.print(); } 	    
      catch (Exception e) { /* handle exception */ }     
    }     
  System.exit(0);   
  }


  public int print(Graphics g, PageFormat pf, int pageIndex)
  throws PrinterException 
  {     
    // pageIndex 0 to 4 corresponds to page numbers 1 to 5.
    if (pageIndex >= 5) return Printable.NO_SUCH_PAGE;
    Graphics2D g2 = (Graphics2D) g;
    // Use the font defined above
    g2.setFont(fnt);
    // Use the gradient color defined above
    g2.setPaint(pnt);
    g2.drawString("Page " + (pageIndex+1), 100f, 100f);
    return Printable.PAGE_EXISTS;   
  } 
}

7.3.2 Printing a File


When a page painter's print method is invoked several times for the same page, it must generate the same output each time.

There are many ways to ensure that repeated requests to render a page yield the same output. For example, to ensure that the same output is generated each time the printing system requests a particular page of a text file, page painter could either store and reuse file pointers for each page or store the actual page data.

In the following example, a "listing" of a text file is printed. The name of the file is passed as an argument to the main method. The PrintListingPainter class stores the file pointer in effect at the beginning of each new page it is asked to render. When the same page is rendered again, the file pointer is reset to the remembered position.

import java.awt.*; 
import java.awt.print.*; 
import java.io.*;

public class PrintListing 
{   
  public static void main(String[] args) 
  {     
    // Get a PrinterJob
    PrinterJob job = PrinterJob.getPrinterJob();
    // Ask user for page format (e.g., portrait/landscape)
    PageFormat pf = job.pageDialog(job.defaultPage());
    // Specify the Printable is an instance of
    // PrintListingPainter; also provide given PageFormat
    job.setPrintable(new PrintListingPainter(args[0]), pf);
    // Print 1 copy   
    job.setCopies(1);     
    // Put up the dialog box     
    if (job.printDialog()) 
    {
      // Print the job if the user didn't cancel printing
      try { job.print(); }
      catch (Exception e) { /* handle exception */ }     
    }     
    System.exit(0);   
  } 
}

class PrintListingPainter implements Printable 
{
  private RandomAccessFile raf;   
  private String fileName;   
  private Font fnt = new Font("Helvetica", Font.PLAIN, 10);
  private int rememberedPageIndex = -1;   
  private long rememberedFilePointer = -1;   
  private boolean rememberedEOF = false;

  public PrintListingPainter(String file) 
  { 
    fileName = file;     
    try
    { 
      // Open file 	
      raf = new RandomAccessFile(file, "r");     
    } 
    catch (Exception e) { rememberedEOF = true; }   
  }

  public int print(Graphics g, PageFormat pf, int pageIndex)
  throws PrinterException 
  {
  try 
  { 
    // For catching IOException     
    if (pageIndex != rememberedPageIndex) 
    { 
      // First time we've visited this page
      rememberedPageIndex = pageIndex; 	
      // If encountered EOF on previous page, done 
      if (rememberedEOF) return Printable.NO_SUCH_PAGE;
      // Save current position in input file
      rememberedFilePointer = raf.getFilePointer();
    } 
    else raf.seek(rememberedFilePointer);
    g.setColor(Color.black);     
    g.setFont(fnt); 
	int x = (int) pf.getImageableX() + 10;
	int y = (int) pf.getImageableY() + 12;    
    // Title line     
    g.drawString("File: " + fileName+", page: " + (pageIndex+1), 
                  x, y);
    // Generate as many lines as will fit in imageable area
    y += 36;
    while (y + 12 < pf.getImageableY()+pf.getImageableHeight())
    {
      String line = raf.readLine();
      if (line == null)
      { 
        rememberedEOF = true;
        break; 
		}
        g.drawString(line, x, y); 
        y += 12;     
      }
      return Printable.PAGE_EXISTS;    
    } 
    catch (Exception e) { return Printable.NO_SUCH_PAGE;}
  } 
}


CONTENTS | PREV | NEXT
Copyright © 1997-1998 Sun Microsystems, Inc. All Rights Reserved.