[ Team LiB ] Previous Section Next Section

13.2 Printing with the Java 1.2 API

Example 13-2 is a listing of JuliaSet2. This subclass of Example 13-1 displays a different Julia set (pictured in Figure 13-2) and overrides the print( ) method, to demonstrate printing out the set using the Java 1.2 API. Like its superclass, JuliaSet2 should be tested using the ShowBean program.

Figure 13-2. A Julia set printed with the Java 1.2 API

The key to this example is the inner class PrintableComponent, which implements the java.awt.print.Printable interface to print a component and a title for that component. Pay attention to the return value of the Printable.print( ) method: the Printable interface can represent multipage documents, and uses its return value to tell the printing system when the last page of the document has been reached.

The java.awt.print package also defines an interface named Pageable, which is useful for defining multipage documents for which the number of pages is known in advance. It allows different pages of the document to be printed using different PageFormat objects, which allows for different margins, orientations, and so forth. Pageable documents are not demonstrated in this chapter.

Example 13-2. JuliaSet2.java
package je3.print;
import javax.swing.*;
import java.awt.*;
import java.awt.print.*; // This package is the Java 1.2 printing API

 * This class extends JuliaSet1 and overrides the print( ) method to demonstrate
 * the Java 1.2 printing API.
public class JuliaSet2 extends JuliaSet1 {
    public JuliaSet2( ) { this(.4, .4); }  // Display a different set by default
    public JuliaSet2(double cx, double cy) { super(cx,cy); }

    // This method demonstrates the Java 1.2 printing API.
    // Test it using the ShowBean program.
    public void print( ) {
        // Java 1.1 used java.awt.PrintJob.
        // In Java 1.2 we use java.awt.print.PrinterJob
        PrinterJob job = PrinterJob.getPrinterJob( );

        // Alter the default page settings to request landscape mode
        PageFormat page = job.defaultPage( );
        page.setOrientation(PageFormat.LANDSCAPE);  // landscape by default

        // Tell the PrinterJob what Printable object we want to print.
        // PrintableComponent is defined as an inner class below
        String title = "Julia set for c={" + cx + "," + cy + "}";
        Printable printable = new PrintableComponent(this, title);
        job.setPrintable(printable, page);

        // Call the printDialog( ) method to give the user a chance to alter
        // the printing attributes or to cancel the printing request.
        if (job.printDialog( )) {
            // If we get here, then the user did not cancel the print job
            // So start printing, displaying a dialog for errors.
            try { job.print( ); }
            catch(PrinterException e) {
                JOptionPane.showMessageDialog(this, e.toString( ),

    // This inner class implements the Printable interface for an AWT component
    public static class PrintableComponent implements Printable {
        Component c;
        String title;
        public PrintableComponent(Component c, String title) {
            this.c = c;
            this.title = title;

        // This method should print the specified page number to the specified
        // Graphics object, abiding by the specified page format.
        // The printing system will call this method repeatedly to print all
        // pages of the print job.  If pagenum is greater than the last page,
        // it should return NO_SUCH_PAGE to indicate that it is done.  The
        // printing system may call this method multiple times per page.
        public int print(Graphics g, PageFormat format, int pagenum) {
            // This implemenation is always a single page
            if (pagenum > 0) return Printable.NO_SUCH_PAGE;

            // The Java 1.2 printing API passes us a Graphics object, but we
            // can always cast it to a Graphics2D object
            Graphics2D g2 = (Graphics2D) g;

            // Translate to accomodate the requested top and left margins.
            g2.translate(format.getImageableX( ), format.getImageableY( ));

            // Figure out how big the drawing is, and how big the page 
            // (excluding margins) is
            Dimension size = c.getSize( );                  // component size
            double pageWidth = format.getImageableWidth( );    // Page width
            double pageHeight = format.getImageableHeight( );  // Page height

            // If the component is too wide or tall for the page, scale it down
            if (size.width > pageWidth) {
                double factor = pageWidth/size.width; // How much to scale
                g2.scale(factor, factor);           // Adjust coordinate system
                pageWidth /= factor;                // Adjust page size up
                pageHeight /= factor;
            if (size.height > pageHeight) {   // Do the same thing for height
                double factor = pageHeight/size.height;
                g2.scale(factor, factor);
                pageWidth /= factor;
                pageHeight /= factor;

            // Now we know the component will fit on the page.  Center it by
            // translating as necessary.

            // Draw a line around the outside of the drawing area and label it
            g2.drawRect(-1, -1, size.width+2, size.height+2);
            g2.drawString(title, 0, -15);

            // Set a clipping region so the component can't draw outside of
            // its own bounds.
            g2.setClip(0, 0, size.width, size.height);

            // Finally, print the component by calling its paint( ) method.
            // This prints the background, border, and children as well.
            // For Swing components, if you don't want the background, border,
            // and children, then call printComponent( ) instead.

            // Tell the PrinterJob that the page number was valid
            return Printable.PAGE_EXISTS;
    [ Team LiB ] Previous Section Next Section