JMU
Printing
An Introduction with Examples in Java


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu


Overview
The Printable Interface
Job Control
Controlling the Process
javaexamples/printing/PrinterController.java
import java.awt.print.*;
import javax.swing.*;

/**
 * A utility class for controlling the printing process.
 * 
 * @author Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class PrinterController
{
    /**
     * Print the given Printable (displaying any error messages in
     * a JOptionPane).
     * 
     * @param printable  The Printable to print
     * @param parent     The parent JFrame
     */
    public static void print(Printable printable, JFrame parent)
    {
        PrinterJob job = PrinterJob.getPrinterJob();
        try
        {
            job.setPrintable(printable);
            boolean shouldPrint = job.printDialog();
            if (shouldPrint) job.print();
        }
        catch (Exception e)
        {
            JOptionPane.showMessageDialog(parent, 
                                          "Unable to print!",
                                          "Error", JOptionPane.ERROR_MESSAGE);
        }
    }
}
        
A Wrapper for an Image
javaexamples/printing/PrintableImage.java
import java.awt.*;
import java.awt.print.*;
import java.io.*;
import javax.imageio.*;
import javax.swing.*;

/**
 * A "Printable" version of an Image
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class PrintableImage implements Printable
{
    private double        height, width;
    private Image         image;
    
    /**
     * Explicit Value Constructor
     *
     * @param file   The name of the file containing the image
     */
    public PrintableImage(String file) throws IOException
    {
       image   = ImageIO.read(new File(file));
       width   = image.getWidth(null);
       height  = image.getHeight(null);
    }


    /**
     * Print the image (required by Printable)
     *
     * @param g      The rendering engine
     * @param format The format of the page
     * @param page   The page number
     */
    public int print(Graphics g, PageFormat format, int page)
    {
       double        h, w;
       Graphics2D    g2;
       int           status, x, y;


       g2 = (Graphics2D)g;
       status = Printable.NO_SUCH_PAGE;
       if (page == 0) 
       {
          h = format.getHeight();
          w = format.getWidth(); 

          // Calculatethe position that centers the image
          x = (int)(w/2.0  - width/2.0);
          y = (int)(h/2.0 - height/2.0);

          // Draw the image (as with any rendering engine)
          g2.drawImage(image, x, y, null);

          // Inform the caller that a page has been drawn
          status = Printable.PAGE_EXISTS;
       }
       return status;
    }
}
        
A Wrapper for a JComponent
javaexamples/printing/DelegatingPrintable.java
import java.awt.*;
import java.awt.print.*;
import javax.swing.*;

/**
 * A DelegatingPrintable is a Printable that delegates to a JComponent
 * for the rendering
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class DelegatingPrintable implements Printable
{
    private boolean          doubleBuffered;
    private JComponent       delegate;


    /**
     * Explicit Value Constructor
     *
     * @param delegate    The JComponent to delegate to
     */
    public DelegatingPrintable(JComponent delegate)
    {
       this.delegate = delegate;

       doubleBuffered = delegate.isDoubleBuffered();
    }


    /**
     * Print  (required by Printable)
     *
     * @param g      The rendering engine
     * @param format The format of the page
     * @param page   The page number
     */
    public int print(Graphics g, PageFormat format, int page)
    {
       double        cH, cW, h, scale, w, x, y;
       Graphics2D    g2;
       int           status;

       g2 = (Graphics2D)g;

       // Turn off double buffering
       delegate.setDoubleBuffered(false);

       status = Printable.NO_SUCH_PAGE;
       if (page == 0) 
       {
          // Translate the origin
          x = format.getImageableX();
          y = format.getImageableY();
          g2.translate(x, y);

          // Scale the coordinate system (without changing the
          // aspect ratio)
          h = format.getImageableHeight();
          w = format.getImageableWidth(); 
          cW = (double)(delegate.getWidth());
          cH = (double)(delegate.getHeight());
          scale = Math.min(w/cW, h/cH);
          g2.scale(scale, scale);

          // Have the JComponent paint itself
          delegate.paint(g2);

          // Inform the caller that a page has been drawn
          status = Printable.PAGE_EXISTS;
       }

       // Restore double buffering (if it was on)
       delegate.setDoubleBuffered(doubleBuffered);

       return status;
    }
}
        
Printing Multiple Pages