Java Tutorial/2D Graphics/Print

Материал из Java эксперт
Версия от 15:25, 31 мая 2010; Admin (обсуждение | вклад) (1 версия)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

extends JuliaSet1 and overrides the print() method to demonstrate the Java 1.2 printing API

/*
 * Copyright (c) 2004 David Flanagan.  All rights reserved.
 * This code is from the book Java Examples in a Nutshell, 3nd Edition.
 * It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.
 * You may study, use, and modify it for any non-commercial purpose,
 * including teaching and use in open-source projects.
 * You may distribute it non-commercially as long as you retain this notice.
 * For a commercial use license, or to purchase the book, 
 * please visit http://www.davidflanagan.ru/javaexamples3.
 */
//package je3.print;
import java.awt.ruponent;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.JobAttributes;
import java.awt.PageAttributes;
import java.awt.PrintJob;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
/**
 * 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(), "PrinterException",
            JOptionPane.ERROR_MESSAGE);
      }
    }
  }
  // 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.
      g2.translate((pageWidth - size.width) / 2, (pageHeight - size.height) / 2);
      // 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 won 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.
      c.paint(g);
      // Tell the PrinterJob that the page number was valid
      return Printable.PAGE_EXISTS;
    }
  }
}
class JuliaSet1 extends JComponent {
  // These constants are hard-coded for simplicity
  double x1 = -1.5, y1 = -1.5, x2 = 1.5, y2 = 1.5; // Region of complex plane
  int width = 400, height = 400; // Mapped to these pixels
  double cx, cy; // This complex constant defines the set we display
  BufferedImage image; // The image we compute
  // We compute values between 0 and 63 for each point in the complex plane.
  // This array holds the color values for each of those values.
  static int[] colors;
  static { // Static initializer for the colors[] array.
    colors = new int[64];
    for (int i = 0; i < colors.length; i++) {
      colors[63 - i] = (i * 4 << 16) + (i * 4 << 8) + i * 4; // grayscale
      // (i*4) ^ ((i * 3)<<6) ^ ((i * 7)<<13); // crazy technicolor
    }
  }
  // No-arg constructor with default values for cx, cy.
  public JuliaSet1() {
    this(-1, 0);
  }
  // This constructor specifies the {cx,cy} constant.
  // For simplicity, the other constants remain hardcoded.
  public JuliaSet1(double cx, double cy) {
    this.cx = cx;
    this.cy = cy;
    setPreferredSize(new Dimension(width, height));
    computeImage();
  }
  // This method computes a color value for each pixel of the image
  void computeImage() {
    // Create the image
    image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    // Now loop through the pixels
    int i, j;
    double x, y;
    double dx = (x2 - x1) / width;
    double dy = (y2 - y1) / height;
    for (j = 0, y = y1; j < height; j++, y += dy) {
      for (i = 0, x = x1; i < width; i++, x += dx) {
        // For each pixel, call testPoint() to determine a value.
        // Then map that value to a color and set it in the image.
        // If testPoint() returns 0, the point is part of the Julia set
        // and is displayed in black. If it returns 63, the point is
        // displayed in white. Values in-between are displayed in
        // varying shades of gray.
        image.setRGB(i, j, colors[testPoint(x, y)]);
      }
    }
  }
  // This is the key method for computing Julia sets. For each point z
  // in the complex plane, we repeatedly compute z = z*z + c using complex
  // arithmetic. We stop iterating when the magnitude of z exceeds 2 or
  // after 64 iterations. We return the number of iterations-1.
  public int testPoint(double zx, double zy) {
    for (int i = 0; i < colors.length; i++) {
      // Compute z = z*z + c;
      double newx = zx * zx - zy * zy + cx;
      double newy = 2 * zx * zy + cy;
      zx = newx;
      zy = newy;
      // Check magnitude of z and return iteration number
      if (zx * zx + zy * zy > 4)
        return i;
    }
    return colors.length - 1;
  }
  // This method overrides JComponent to display the julia set.
  // Just scale the image to fit and draw it.
  public void paintComponent(Graphics g) {
    g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
  }
  // This method demonstrates the Java 1.1 java.awt.PrintJob printing API.
  // It also demonstrates the JobAttributes and PageAttributes classes
  // added in Java 1.3. Display the Julia set with ShowBean and use
  // the Command menu to invoke this print command.
  public void print() {
    // Create some attributes objects. This is Java 1.3 stuff.
    // In Java 1.1, we"d use a java.util.Preferences object instead.
    JobAttributes jattrs = new JobAttributes();
    PageAttributes pattrs = new PageAttributes();
    // Set some example attributes: monochrome, landscape mode
    pattrs.setColor(PageAttributes.ColorType.MONOCHROME);
    pattrs.setOrientationRequested(PageAttributes.OrientationRequestedType.LANDSCAPE);
    // Print to file by default
    jattrs.setDestination(JobAttributes.DestinationType.FILE);
    jattrs.setFileName("juliaset.ps");
    // Look up the Frame that holds this component
    Component frame = this;
    while (!(frame instanceof Frame))
      frame = frame.getParent();
    // Get a PrintJob object to print the Julia set with.
    // The getPrintJob() method displays a print dialog and allows the user
    // to override and modify the default JobAttributes and PageAttributes
    Toolkit toolkit = this.getToolkit();
    PrintJob job = toolkit.getPrintJob((Frame) frame, "JuliaSet1", jattrs, pattrs);
    // We get a null PrintJob if the user clicked cancel
    if (job == null)
      return;
    // Get a Graphics object from the PrintJob.
    // We print simply by drawing to this Graphics object.
    Graphics g = job.getGraphics();
    // Center the image on the page
    Dimension pagesize = job.getPageDimension(); // how big is page?
    Dimension panesize = this.getSize(); // how big is image?
    g.translate((pagesize.width - panesize.width) / 2, // center it
        (pagesize.height - panesize.height) / 2);
    // Draw a box around the Julia Set and label it
    g.drawRect(-1, -1, panesize.width + 2, panesize.height + 2);
    g.drawString("Julia Set for c={" + cx + "," + cy + "}", 0, -15);
    // Set a clipping region
    g.setClip(0, 0, panesize.width, panesize.height);
    // Now print the component by calling its paint method
    this.paint(g);
    // Finally tell the printer we"re done with the page.
    // No output will be generated if we don"t call dispose() here.
    g.dispose();
  }
}





implements Printable

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
public class Main implements Printable {
  private static Font sFont = new Font("Serif", Font.PLAIN, 64);
  public int print(Graphics g, PageFormat Pf, int pageIndex) throws PrinterException {
    if (pageIndex > 0)
      return NO_SUCH_PAGE;
    Graphics2D g2 = (Graphics2D) g;
    g2.setFont(sFont);
    g2.setPaint(Color.black);
    g2.drawString("Save a tree!", 96, 144);
    return PAGE_EXISTS;
  }
  public static void main(String[] args) {
    PrinterJob job = PrinterJob.getPrinterJob();
    job.setPrintable(new Main());
    if (job.printDialog()) {
      try {
        job.print();
      } catch (PrinterException e) {
      }
    }
    System.exit(0);
  }
}





javax.print API and allows you to list available printers, query a named printer, print text and image files to a printer, and print to postscript files

/*
 * Copyright (c) 2004 David Flanagan.  All rights reserved.
 * This code is from the book Java Examples in a Nutshell, 3nd Edition.
 * It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.
 * You may study, use, and modify it for any non-commercial purpose,
 * including teaching and use in open-source projects.
 * You may distribute it non-commercially as long as you retain this notice.
 * For a commercial use license, or to purchase the book, 
 * please visit http://www.davidflanagan.ru/javaexamples3.
 */
//package je3.print;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintException;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.StreamPrintService;
import javax.print.StreamPrintServiceFactory;
import javax.print.attribute.Attribute;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Chromaticity;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.Finishings;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.NumberUp;
import javax.print.attribute.standard.OrientationRequested;
import javax.print.attribute.standard.SheetCollate;
import javax.print.attribute.standard.Sides;
import javax.print.event.PrintJobAdapter;
import javax.print.event.PrintJobEvent;
/**
 * This utility program demonstrates the javax.print API and allows you to list
 * available printers, query a named printer, print text and image files to a
 * printer, and print to postscript files.
 * 
 * Usage: java Print -i inputfile [-q] [-p printer] [-ps outputfile]
 * [attributes]
 */
public class Print {
  public static void main(String[] args) throws IOException {
    // These are values we"ll set from the command-line arguments
    boolean query = false;
    String printerName = null;
    String inputFileName = null;
    String outputFileName = null;
    String outputFileType = null;
    PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
    // Loop through the arguments
    for (int i = 0; i < args.length; i++) {
      if (args[i].equals("-q"))
        query = true; // Is this is query?
      else if (args[i].equals("-p")) // Specific printer name
        printerName = args[++i];
      else if (args[i].equals("-i")) // The file to print
        inputFileName = args[++i];
      else if (args[i].equals("-ps")) { // Print it to this file
        // Sun"s Java 1.4 implementation only supports PostScript
        // output. Other implementations might offer PDF, for example.
        outputFileName = args[++i];
        outputFileType = "application/postscript";
      }
      // The rest of the arguments represent common printing attributes
      else if (args[i].equals("-color")) // Request a color printer
        attributes.add(Chromaticity.COLOR);
      else if (args[i].equals("-landscape")) // Request landscape mode
        attributes.add(OrientationRequested.LANDSCAPE);
      else if (args[i].equals("-letter")) // US Letter-size paper
        attributes.add(MediaSizeName.NA_LETTER);
      else if (args[i].equals("-a4")) // European A4 paper
        attributes.add(MediaSizeName.ISO_A4);
      else if (args[i].equals("-staple")) // Request stapling
        attributes.add(Finishings.STAPLE);
      else if (args[i].equals("-collate")) // Collate multiple copies
        attributes.add(SheetCollate.COLLATED);
      else if (args[i].equals("-duplex")) // Request 2-sided
        attributes.add(Sides.DUPLEX);
      else if (args[i].equals("-2")) // 2 pages to a sheet
        attributes.add(new NumberUp(2));
      else if (args[i].equals("-copies")) // how many copies
        attributes.add(new Copies(Integer.parseInt(args[++i])));
      else {
        System.out.println("Unknown argument: " + args[i]);
        System.exit(1);
      }
    }
    if (query) {
      // If the -q argument was specified, but no printer was named,
      // then list all available printers that can support the attributes
      if (printerName == null)
        queryServices(attributes);
      // Otherwise, look for a named printer that can support the
      // attributes and print its status
      else
        queryPrinter(printerName, attributes);
    } else if (outputFileName != null)
      // If this is not a query and we have a filename, print to a file
      printToFile(outputFileName, outputFileType, inputFileName, attributes);
    else
      // Otherwise, print to the named printer, or to the default
      // printer otherwise.
      print(printerName, inputFileName, attributes);
    // The main() method ends here, but there may be a printing thread
    // operating in the background. So the program may not terminate
    // until printing completes.
  }
  // List names of all PrintServices that can support the attributes
  public static void queryServices(PrintRequestAttributeSet attributes) {
    // Find all services that can support the specified attributes
    PrintService[] services = PrintServiceLookup.lookupPrintServices(null, attributes);
    // Loop through available services
    for (int i = 0; i < services.length; i++) {
      // Print service name
      System.out.print(services[i].getName());
      // Then query and print the document types it can print
      DocFlavor[] flavors = services[i].getSupportedDocFlavors();
      for (int j = 0; j < flavors.length; j++) {
        // Filter out DocFlavors that have a representation class other
        // than java.io.InputStream.
        String repclass = flavors[j].getRepresentationClassName();
        if (!repclass.equals("java.io.InputStream"))
          continue;
        System.out.println("\t" + flavors[j].getMimeType());
      }
    }
  }
  // List details about the named printer
  public static void queryPrinter(String printerName, PrintRequestAttributeSet attributes) {
    // Find the named printer
    PrintService service = getNamedPrinter(printerName, attributes);
    if (service == null) {
      System.out.println(printerName + ": no such printer capable of "
          + "handling the specified attributes");
      return;
    }
    // Print status and other information about the printer
    System.out.println(printerName + " status:");
    Attribute[] attrs = service.getAttributes().toArray();
    for (int i = 0; i < attrs.length; i++)
      System.out.println("\t" + attrs[i].getName() + ": " + attrs[i]);
  }
  // Print the contents of the named file to the named printer (or to a
  // default printer if printerName is null) requesting the specified
  // attributes.
  public static void print(String printerName, String filename, PrintRequestAttributeSet attributes)
      throws IOException {
    // Look for a printer that can support the attributes
    PrintService service = getNamedPrinter(printerName, attributes);
    if (service == null) {
      System.out.println("Can"t find a printer " + "with specified attributes");
      return;
    }
    // Print the file to that printer. See method definition below
    printToService(service, filename, attributes);
    // Let the user know where to pick up their printout
    System.out.println("Printed " + filename + " to " + service.getName());
  }
  // Print to an output file instead of a printer
  public static void printToFile(String outputFileName, String outputFileType,
      String inputFileName, PrintRequestAttributeSet attributes) throws IOException {
    // Determine whether the system can print to the specified type, and
    // get a factory object if so.
    // The name of this static method is way too long!
    StreamPrintServiceFactory[] factories = StreamPrintServiceFactory
        .lookupStreamPrintServiceFactories(null, outputFileType);
    // Error message if we can"t print to the specified output type
    if (factories.length == 0) {
      System.out.println("Unable to print files of type: " + outputFileType);
      return;
    }
    // Open the output file
    FileOutputStream out = new FileOutputStream(outputFileName);
    // Get a PrintService object to print to that file
    StreamPrintService service = factories[0].getPrintService(out);
    // Print using the method below
    printToService(service, inputFileName, attributes);
    // And remember to close the output file
    out.close();
  }
  // Print the contents of the named file to the specified PrintService,
  // requesting the specified attributes.
  // This is shared code used by print() and printToFile() above.
  public static void printToService(PrintService service, String filename,
      PrintRequestAttributeSet attributes) throws IOException {
    // Figure out what type of file we"re printing
    DocFlavor flavor = getFlavorFromFilename(filename);
    // Open the file
    InputStream in = new FileInputStream(filename);
    // Create a Doc object to print from the file and flavor.
    Doc doc = new SimpleDoc(in, flavor, null);
    // Create a print job from the service
    DocPrintJob job = service.createPrintJob();
    // Monitor the print job with a listener
    job.addPrintJobListener(new PrintJobAdapter() {
      public void printJobCompleted(PrintJobEvent e) {
        System.out.println("Print job complete");
        System.exit(0);
      }
      public void printDataTransferCompleted(PrintJobEvent e) {
        System.out.println("Document transfered to printer");
      }
      public void printJobRequiresAttention(PrintJobEvent e) {
        System.out.println("Print job requires attention");
        System.out.println("Check printer: out of paper?");
      }
      public void printJobFailed(PrintJobEvent e) {
        System.out.println("Print job failed");
        System.exit(1);
      }
    });
    // Now print the document, catching errors
    try {
      job.print(doc, attributes);
    } catch (PrintException e) {
      System.out.println(e);
      System.exit(1);
    }
  }
  // A utility method to look up printers that can support the specified
  // attributes and return the one that matches the specified name.
  public static PrintService getNamedPrinter(String name, PrintRequestAttributeSet attrs) {
    PrintService[] services = PrintServiceLookup.lookupPrintServices(null, attrs);
    if (services.length > 0) {
      if (name == null)
        return services[0];
      else {
        for (int i = 0; i < services.length; i++) {
          if (services[i].getName().equals(name))
            return services[i];
        }
      }
    }
    return null;
  }
  // A utility method to return a DocFlavor object matching the
  // extension of the filename.
  public static DocFlavor getFlavorFromFilename(String filename) {
    String extension = filename.substring(filename.lastIndexOf(".") + 1);
    extension = extension.toLowerCase();
    if (extension.equals("gif"))
      return DocFlavor.INPUT_STREAM.GIF;
    else if (extension.equals("jpeg"))
      return DocFlavor.INPUT_STREAM.JPEG;
    else if (extension.equals("jpg"))
      return DocFlavor.INPUT_STREAM.JPEG;
    else if (extension.equals("png"))
      return DocFlavor.INPUT_STREAM.PNG;
    else if (extension.equals("ps"))
      return DocFlavor.INPUT_STREAM.POSTSCRIPT;
    else if (extension.equals("txt"))
      return DocFlavor.INPUT_STREAM.TEXT_PLAIN_HOST;
    // Fallback: try to determine flavor from file content
    else
      return DocFlavor.INPUT_STREAM.AUTOSENSE;
  }
}





Pagination during print

/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.UIManager;
public class PaginationExample implements Printable, ActionListener {
  int[] pageBreaks; // array of page break line positions.
  /* Synthesise some sample lines of text */
  String[] textLines;
  private void initTextLines() {
    if (textLines == null) {
      int numLines = 200;
      textLines = new String[numLines];
      for (int i = 0; i < numLines; i++) {
        textLines[i] = "This is line number " + i;
      }
    }
  }
  public int print(Graphics g, PageFormat pf, int pageIndex)
      throws PrinterException {
    Font font = new Font("Serif", Font.PLAIN, 10);
    FontMetrics metrics = g.getFontMetrics(font);
    int lineHeight = metrics.getHeight();
    if (pageBreaks == null) {
      initTextLines();
      int linesPerPage = (int) (pf.getImageableHeight() / lineHeight);
      int numBreaks = (textLines.length - 1) / linesPerPage;
      pageBreaks = new int[numBreaks];
      for (int b = 0; b < numBreaks; b++) {
        pageBreaks[b] = (b + 1) * linesPerPage;
      }
    }
    if (pageIndex > pageBreaks.length) {
      return NO_SUCH_PAGE;
    }
    /*
     * User (0,0) is typically outside the imageable area, so we must translate
     * by the X and Y values in the PageFormat to avoid clipping Since we are
     * drawing text we
     */
    Graphics2D g2d = (Graphics2D) g;
    g2d.translate(pf.getImageableX(), pf.getImageableY());
    /*
     * Draw each line that is on this page. Increment "y" position by lineHeight
     * for each line.
     */
    int y = 0;
    int start = (pageIndex == 0) ? 0 : pageBreaks[pageIndex - 1];
    int end = (pageIndex == pageBreaks.length) ? textLines.length
        : pageBreaks[pageIndex];
    for (int line = start; line < end; line++) {
      y += lineHeight;
      g.drawString(textLines[line], 0, y);
    }
    /* tell the caller that this page is part of the printed document */
    return PAGE_EXISTS;
  }
  public void actionPerformed(ActionEvent e) {
    PrinterJob job = PrinterJob.getPrinterJob();
    job.setPrintable(this);
    boolean ok = job.printDialog();
    if (ok) {
      try {
        job.print();
      } catch (PrinterException ex) {
        /* The job did not successfully complete */
      }
    }
  }
  public static void main(String args[]) {
    try {
      String cn = UIManager.getSystemLookAndFeelClassName();
      UIManager.setLookAndFeel(cn); // Use the native L&F
    } catch (Exception cnf) {
    }
    JFrame f = new JFrame("Printing Pagination Example");
    f.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    JButton printButton = new JButton("Print Pages");
    printButton.addActionListener(new PaginationExample());
    f.add("Center", printButton);
    f.pack();
    f.setVisible(true);
  }
}





Print an image out

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.swing.ImageIcon;
public class ImagePrint {
  public static void main(String[] args) throws Exception {
    PrintService service = PrintServiceLookup.lookupDefaultPrintService();
    DocPrintJob job = service.createPrintJob();
    DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
    SimpleDoc doc = new SimpleDoc(new MyPrintable(), flavor, null);
    job.print(doc, null);
  }
}
class MyPrintable implements Printable {
  ImageIcon printImage = new javax.swing.ImageIcon("a.gif");
  public int print(Graphics g, PageFormat pf, int pageIndex) {
    Graphics2D g2d = (Graphics2D) g;
    g.translate((int) (pf.getImageableX()), (int) (pf.getImageableY()));
    if (pageIndex == 0) {
      double pageWidth = pf.getImageableWidth();
      double pageHeight = pf.getImageableHeight();
      double imageWidth = printImage.getIconWidth();
      double imageHeight = printImage.getIconHeight();
      double scaleX = pageWidth / imageWidth;
      double scaleY = pageHeight / imageHeight;
      double scaleFactor = Math.min(scaleX, scaleY);
      g2d.scale(scaleFactor, scaleFactor);
      g.drawImage(printImage.getImage(), 0, 0, null);
      return Printable.PAGE_EXISTS;
    }
    return Printable.NO_SUCH_PAGE;
  }
}





PrinterJob and Printable

/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.UIManager;
public class HelloWorldPrinter implements Printable, ActionListener {
  public int print(Graphics g, PageFormat pf, int page) throws PrinterException {
    if (page > 0) { /* We have only one page, and "page" is zero-based */
      return NO_SUCH_PAGE;
    }
    /*
     * User (0,0) is typically outside the imageable area, so we must translate
     * by the X and Y values in the PageFormat to avoid clipping
     */
    Graphics2D g2d = (Graphics2D) g;
    g2d.translate(pf.getImageableX(), pf.getImageableY());
    /* Now we perform our rendering */
    g.drawString("Hello world!", 100, 100);
    /* tell the caller that this page is part of the printed document */
    return PAGE_EXISTS;
  }
  public void actionPerformed(ActionEvent e) {
    PrinterJob job = PrinterJob.getPrinterJob();
    job.setPrintable(this);
    boolean ok = job.printDialog();
    if (ok) {
      try {
        job.print();
      } catch (PrinterException ex) {
        /* The job did not successfully complete */
      }
    }
  }
  public static void main(String args[]) {
    UIManager.put("swing.boldMetal", Boolean.FALSE);
    JFrame f = new JFrame("Hello World Printer");
    f.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    JButton printButton = new JButton("Print Hello World");
    printButton.addActionListener(new HelloWorldPrinter());
    f.add("Center", printButton);
    f.pack();
    f.setVisible(true);
  }
}





Print Image

import java.io.FileInputStream;
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Copies;
public class Main {
  static public void main(String args[]) throws Exception {
    PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
    pras.add(new Copies(1));
    PrintService pss[] = PrintServiceLookup.lookupPrintServices(DocFlavor.INPUT_STREAM.GIF, pras);
    PrintService ps = pss[0];
    System.out.println("Printing to " + ps);
    DocPrintJob job = ps.createPrintJob();
    FileInputStream fin = new FileInputStream("filename.gif");
    Doc doc = new SimpleDoc(fin, DocFlavor.INPUT_STREAM.GIF, null);
    job.print(doc, pras);
    fin.close();
  }
}





Printing Pages with Different Formats

import java.awt.Graphics;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
class PrintBook {
  public static void main(String[] args) {
    PrinterJob pjob = PrinterJob.getPrinterJob();
    Book book = new Book();

    PageFormat landscape = pjob.defaultPage();
    landscape.setOrientation(PageFormat.LANDSCAPE);
    book.append(new Printable1(), landscape);
    PageFormat portrait = pjob.defaultPage();
    portrait.setOrientation(PageFormat.PORTRAIT);
    book.append(new Printable2(), portrait, 5);
    pjob.setPageable(book);
    try {
      pjob.print();
    } catch (PrinterException e) {
    }
  }
}
class Printable1 implements Printable {
  public int print(Graphics g, PageFormat pf, int pageIndex) {
    drawGraphics(g, pf);
    return Printable.PAGE_EXISTS;
  }
  public void drawGraphics(Graphics g, PageFormat pf){
    
  }
}
class Printable2 implements Printable {
  public int print(Graphics g, PageFormat pf, int pageIndex) {
    drawGraphics(g, pf);
    return Printable.PAGE_EXISTS;
  }
  public void drawGraphics(Graphics g, PageFormat pf){
    
  }
}





Printing to a File

import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Destination;
public class Main {
  public static void main(String[] argv) throws Exception {
    // Set up destination attribute
    PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
    aset.add(new Destination(new java.net.URI("file:e:/temp/out.ps")));
  }
}





Print out a Swing component

/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
public class PrintUIWindow implements Printable, ActionListener {
  JFrame frameToPrint;
  public int print(Graphics g, PageFormat pf, int page) throws PrinterException {
    if (page > 0) { /* We have only one page, and "page" is zero-based */
      return NO_SUCH_PAGE;
    }
    /*
     * User (0,0) is typically outside the imageable area, so we must translate
     * by the X and Y values in the PageFormat to avoid clipping
     */
    Graphics2D g2d = (Graphics2D) g;
    g2d.translate(pf.getImageableX(), pf.getImageableY());
    /* Now print the window and its visible contents */
    frameToPrint.printAll(g);
    /* tell the caller that this page is part of the printed document */
    return PAGE_EXISTS;
  }
  public void actionPerformed(ActionEvent e) {
    PrinterJob job = PrinterJob.getPrinterJob();
    job.setPrintable(this);
    boolean ok = job.printDialog();
    if (ok) {
      try {
        job.print();
      } catch (PrinterException ex) {
        /* The job did not successfully complete */
      }
    }
  }
  public PrintUIWindow(JFrame f) {
    frameToPrint = f;
  }
  public static void main(String args[]) {
    UIManager.put("swing.boldMetal", Boolean.FALSE);
    JFrame f = new JFrame("Print UI Example");
    f.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    JTextArea text = new JTextArea(50, 20);
    for (int i = 1; i <= 50; i++) {
      text.append("Line " + i + "\n");
    }
    JScrollPane pane = new JScrollPane(text);
    pane.setPreferredSize(new Dimension(250, 200));
    f.add("Center", pane);
    JButton printButton = new JButton("Print This Window");
    printButton.addActionListener(new PrintUIWindow(f));
    f.add("South", printButton);
    f.pack();
    f.setVisible(true);
  }
}





The area of the actual page

import java.awt.Graphics;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.swing.JComponent;
public class BasicPrint extends JComponent implements Printable {
  public int print(Graphics g, PageFormat pf, int pageIndex) {
    double x = 0;
    double y = 0;
    double w = pf.getWidth();
    double h = pf.getHeight();
    return Printable.NO_SUCH_PAGE;
  }
  public static void main(String[] args) {
    PrinterJob pjob = PrinterJob.getPrinterJob();
    PageFormat pf = pjob.defaultPage();
    pjob.setPrintable(new BasicPrint(), pf);
    try {
      pjob.print();
    } catch (PrinterException e) {
    }
  }
}





The area of the printable area

import java.awt.Graphics;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.swing.JComponent;
public class BasicPrint extends JComponent implements Printable {
  public int print(Graphics g, PageFormat pf, int pageIndex) {
    double ix = pf.getImageableX();
    double iy = pf.getImageableY();
    double iw = pf.getImageableWidth();
    double ih = pf.getImageableHeight();
    return Printable.NO_SUCH_PAGE;
  }
  public static void main(String[] args) {
    PrinterJob pjob = PrinterJob.getPrinterJob();
    PageFormat pf = pjob.defaultPage();
    pjob.setPrintable(new BasicPrint(), pf);
    try {
      pjob.print();
    } catch (PrinterException e) {
    }
  }
}





Work with PrintRequestAttributeSet

/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.swing.UIManager;
public class PrintDialogExample implements Printable {
  public int print(Graphics g, PageFormat pf, int page) throws PrinterException {
    if (page > 0) { /* We have only one page, and "page" is zero-based */
      return NO_SUCH_PAGE;
    }
    /*
     * User (0,0) is typically outside the imageable area, so we must translate
     * by the X and Y values in the PageFormat to avoid clipping
     */
    Graphics2D g2d = (Graphics2D) g;
    g2d.translate(pf.getImageableX(), pf.getImageableY());
    /* Now we perform our rendering */
    g.drawString("Test the print dialog!", 100, 100);
    /* tell the caller that this page is part of the printed document */
    return PAGE_EXISTS;
  }
  public static void main(String args[]) {
    try {
      String cn = UIManager.getSystemLookAndFeelClassName();
      UIManager.setLookAndFeel(cn); // Use the native L&F
    } catch (Exception cnf) {
    }
    PrinterJob job = PrinterJob.getPrinterJob();
    PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
    PageFormat pf = job.pageDialog(aset);
    job.setPrintable(new PrintDialogExample(), pf);
    boolean ok = job.printDialog(aset);
    if (ok) {
      try {
        job.print(aset);
      } catch (PrinterException ex) {
        /* The job did not successfully complete */
      }
    }
    System.exit(0);
  }
}