Java/2D Graphics GUI/Print

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

Another print demo

   
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
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.JPanel;
public class AnotherPrintDemo extends JFrame {
  DrawingCanvas canvas;
  JButton setUpButton = new JButton("Page Setup");
  JButton printButton = new JButton("Print");
  JButton cancelButton = new JButton("Cancel");
  public AnotherPrintDemo() {
    super();
    Container container = getContentPane();
    canvas = new DrawingCanvas();
    container.add(canvas);
    JPanel panel = new JPanel(new GridLayout(1, 3));
    ButtonListener buttonListener = new ButtonListener();
    setUpButton.addActionListener(buttonListener);
    panel.add(setUpButton);
    printButton.addActionListener(buttonListener);
    panel.add(printButton);
    cancelButton.addActionListener(buttonListener);
    panel.add(cancelButton);
    container.add(BorderLayout.SOUTH, panel);
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    setSize(650, 275);
    setVisible(true);
  }
  class ButtonListener implements ActionListener {
    PrinterJob printJob;
    PageFormat pageFormat;
    PrintableCanvas printableCanvas;
    ButtonListener() {
      printJob = PrinterJob.getPrinterJob();
      pageFormat = printJob.defaultPage();
    }
    public void actionPerformed(ActionEvent e) {
      JButton tempButton = (JButton) e.getSource();
      if (tempButton.equals(setUpButton)) {
        pageFormat = printJob.pageDialog(pageFormat);
        printJob.validatePage(pageFormat);
      } else if (tempButton.equals(printButton)) {
        printableCanvas = new PrintableCanvas(pageFormat);
        printJob.setPrintable(printableCanvas);
        boolean ok = printJob.printDialog();
        if (ok) {
          try {
            printJob.print();
          } catch (Exception pe) {
            System.out.println("Printing Exception Occured!");
            pe.printStackTrace();
          }
        }
      } else if (tempButton.equals(cancelButton)) {
        printJob.cancel();
      }
    }
  }
  public static void main(String arg[]) {
    new AnotherPrintDemo();
  }
}
class DrawingCanvas extends JPanel {
  Font font;
  FontMetrics fontMetrics;
  int w, h;
  DrawingCanvas() {
    setBackground(Color.white);
    setSize(400, 275);
    w = this.getWidth();
    h = this.getHeight();
    font = new Font("Dialog", Font.BOLD, 50);
    fontMetrics = getFontMetrics(font);
  }
  public void paintComponent(Graphics g) {
    super.paintComponent(g); 
    Graphics2D g2D = (Graphics2D) g;
    paintContent(g2D, w, h);
  }
  public void paintContent(Graphics2D g2D, int w, int h) {
    g2D.setFont(font);
      g2D.drawString("Java Source and Support", 0,
        (float) (0.5 * h - 1.25 * fontMetrics.getHeight()));
  }
}
class PrintableCanvas implements Printable {
  DrawingCanvas canvas;
  PageFormat pageFormat;
  public PrintableCanvas(PageFormat pf) {
    pageFormat = pf;
  }
  public int print(Graphics g, PageFormat pageFormat, int pageIndex)
      throws PrinterException {
    if (pageIndex >= 1) {
      return Printable.NO_SUCH_PAGE;
    }
    Graphics2D g2D = (Graphics2D) g;
    canvas = new DrawingCanvas();
    canvas.paintContent(g2D, (int) pageFormat.getImageableWidth(),
        (int) pageFormat.getImageableHeight());
    // successful printing of the page
    return Printable.PAGE_EXISTS;
  }
}



Book

   
import java.awt.Color;
import java.awt.ruponent;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.font.FontRenderContext;
import java.awt.font.LineMetrics;
import java.awt.geom.Rectangle2D;
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;
import javax.swing.JComponent;
public class Booker {
  public static void main(String[] args) {
    PrinterJob pj = PrinterJob.getPrinterJob();
    // Create two Printables.
    Component c1 = new PatchworkComponent("Printable 1");
    Component c2 = new PatchworkComponent("Printable 2");
    c1.setSize(500, 400);
    c2.setSize(500, 400);
    BookComponentPrintable printable1 = new BookComponentPrintable(c1);
    BookComponentPrintable printable2 = new BookComponentPrintable(c2);
    // Create two PageFormats.
    PageFormat pageFormat1 = pj.defaultPage();
    PageFormat pageFormat2 = (PageFormat) pageFormat1.clone();
    pageFormat2.setOrientation(PageFormat.LANDSCAPE);
    // Create a Book.
    Book book = new Book();
    book.append(printable1, pageFormat1);
    book.append(printable2, pageFormat2);
    // Print the Book.
    pj.setPageable(book);
    if (pj.printDialog()) {
      try {
        pj.print();
      } catch (PrinterException e) {
        System.out.println(e);
      }
    }
  }
}
class PatchworkComponent extends JComponent implements Printable {
  private float mSide = 36;
  private float mOffset = 36;
  private int mColumns = 8;
  private int mRows = 4;
  private String mString = "Java Source and Support";
  private Font mFont = new Font("Serif", Font.PLAIN, 64);
  private Paint mHorizontalGradient, mVerticalGradient;
  public PatchworkComponent() {
    float x = mOffset;
    float y = mOffset;
    float halfSide = mSide / 2;
    float x0 = x + halfSide;
    float y0 = y;
    float x1 = x + halfSide;
    float y1 = y + (mRows * mSide);
    mVerticalGradient = new GradientPaint(x0, y0, Color.darkGray, x1, y1,
        Color.lightGray, true);
    x0 = x;
    y0 = y + halfSide;
    x1 = x + (mColumns * mSide);
    y1 = y + halfSide;
    mHorizontalGradient = new GradientPaint(x0, y0, Color.darkGray, x1, y1,
        Color.lightGray, true);
  }
  public PatchworkComponent(String s) {
    this();
    mString = s;
  }
  public void paintComponent(Graphics g) {
    Graphics2D g2 = (Graphics2D) g;
    g2.rotate(Math.PI / 24, mOffset, mOffset);
    for (int row = 0; row < mRows; row++) {
      for (int column = 0; column < mColumns; column++) {
        float x = column * mSide + mOffset;
        float y = row * mSide + mOffset;
        if (((column + row) % 2) == 0)
          g2.setPaint(mVerticalGradient);
        else
          g2.setPaint(mHorizontalGradient);
        Rectangle2D r = new Rectangle2D.Float(x, y, mSide, mSide);
        g2.fill(r);
      }
    }
    FontRenderContext frc = g2.getFontRenderContext();
    float width = (float) mFont.getStringBounds(mString, frc).getWidth();
    LineMetrics lm = mFont.getLineMetrics(mString, frc);
    float x = ((mColumns * mSide) - width) / 2 + mOffset;
    float y = ((mRows * mSide) + lm.getAscent()) / 2 + mOffset;
    g2.setFont(mFont);
    g2.setPaint(Color.white);
    g2.drawString(mString, x, y);
  }
  public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
    if (pageIndex != 0)
      return NO_SUCH_PAGE;
    paintComponent(g);
    return PAGE_EXISTS;
  }
}
class BookComponentPrintable implements Printable {
  private Component mComponent;
  public BookComponentPrintable(Component c) {
    mComponent = c;
  }
  public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
    Graphics2D g2 = (Graphics2D) g;
    g2.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
    mComponent.paint(g2);
    return PAGE_EXISTS;
  }
}



Book demo

   
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
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;
import java.util.Vector;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.border.TitledBorder;
public class BookDemo extends JFrame {
  DrawingCanvas canvas;
  JRadioButton portraitButton = new JRadioButton("Portrait", true);
  JRadioButton landscapeButton = new JRadioButton("Landscape");
  JRadioButton rLandscapeButton = new JRadioButton("Reverse Landscape");
  JButton addButton = new JButton("Add to Book");
  JButton printButton = new JButton("Print");
  JButton clearButton = new JButton("Clear");
  public BookDemo() {
    super();
    Container container = getContentPane();
    canvas = new DrawingCanvas();
    container.add(canvas);
    JPanel panel = new JPanel(new GridLayout(2, 6));
    container.add(panel, BorderLayout.SOUTH);
    ButtonGroup gp = new ButtonGroup();
    gp.add(portraitButton);
    gp.add(landscapeButton);
    gp.add(rLandscapeButton);
    ActionListener buttonListener = new ButtonListener();
    portraitButton.addActionListener(buttonListener);
    landscapeButton.addActionListener(buttonListener);
    rLandscapeButton.addActionListener(buttonListener);
    panel.add(portraitButton);
    panel.add(landscapeButton);
    panel.add(rLandscapeButton);
    addButton.addActionListener(buttonListener);
    printButton.addActionListener(buttonListener);
    clearButton.addActionListener(buttonListener);
    panel.add(addButton);
    panel.add(printButton);
    panel.add(clearButton);
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    setSize(450, 425);
    setVisible(true);
  }
  public static void main(String arg[]) {
    new BookDemo();
  }
  class ButtonListener implements ActionListener {
    PrinterJob jobControl;
    PageFormat pageFormat;
    Book book;
    ButtonListener() {
      jobControl = PrinterJob.getPrinterJob();
      pageFormat = jobControl.defaultPage();
      book = new Book();
    }
    public void actionPerformed(ActionEvent e) {
      Object obj = e.getSource();
      if (obj instanceof JRadioButton) {
        JRadioButton tempButton = (JRadioButton) obj;
        if (tempButton.equals(portraitButton)) {
          pageFormat.setOrientation(PageFormat.PORTRAIT);
        }
        else if (tempButton.equals(landscapeButton)) {
          pageFormat.setOrientation(PageFormat.LANDSCAPE);
        } else if (tempButton.equals(rLandscapeButton)) {
          pageFormat.setOrientation(PageFormat.REVERSE_LANDSCAPE);
        }
      } else if (obj instanceof JButton) {
        JButton tempButton = (JButton) obj;
        if (tempButton.equals(addButton)) {
          book.append(new PrintableCanvas(canvas.getShapesVector()),
              (PageFormat) pageFormat.clone());
        } else if (tempButton.equals(printButton)) {
          jobControl.setPageable(book);
          if (jobControl.printDialog()) {
            try {
              jobControl.print();
            } catch (Exception pe) {
              System.out.println("Printing Exception Occured!");
              pe.printStackTrace();
            }
          }
        } else if (tempButton.equals(clearButton)) {
          canvas.shapesVector.clear();
          canvas.clear = true;
          canvas.repaint();
        }
      }
    }
  }
  class DrawingCanvas extends Canvas {
    private Vector shapesVector;
    Point2D currPoint, newPoint;
    Line2D line;
    boolean clear = false;
    DrawingCanvas() {
      shapesVector = new Vector();
      addMouseListener(new MouseHandler());
      addMouseMotionListener(new MouseMotionHandler());
      setBackground(Color.white);
      setSize(450, 400); 
    }
    public Vector getShapesVector() {
      return shapesVector;
    }
    public void update(Graphics g) {
      Graphics2D g2D = (Graphics2D) g;
      g2D.setColor(Color.black);
      if (currPoint != null && newPoint != null) {
        line = new Line2D.Float(currPoint, newPoint);
        g2D.draw(line);
        shapesVector.addElement(line);
      }
      currPoint = newPoint; 
      if (clear) {
        g2D.setColor(Color.white);
        g2D.fillRect(0, 0, getWidth(), getHeight());
        clear = false;
      }
    }
    public void paint(Graphics g) {
      Graphics2D g2D = (Graphics2D) g;
      g2D.setColor(Color.black);
      for (int i = 0; i < shapesVector.size(); i++) {
        Line2D.Float line2D = (Line2D.Float) shapesVector.elementAt(i);
        g2D.draw(line2D);
      }
    }
    class MouseHandler extends MouseAdapter {
      public void mousePressed(MouseEvent e) {
        currPoint = newPoint = e.getPoint();
        repaint();
      }
    }
    class MouseMotionHandler extends MouseMotionAdapter {
      public void mouseDragged(MouseEvent e) {
        newPoint = e.getPoint();
        repaint();
      }
    }
  }
  class PrintableCanvas implements Printable {
    private Vector linesVector;
    public PrintableCanvas(Vector vector) {
      linesVector = (Vector) vector.clone();
    }
    public int print(Graphics pg, PageFormat pf, int pi)
        throws PrinterException {
      Graphics2D pg2D = (Graphics2D) pg;
      pg2D.translate(pf.getImageableX(), pf.getImageableY());
      pg2D.setPaint(Color.green);
      pg2D.drawString(" ", 100, 100);
      pg2D.setPaint(Color.black);
      for (int i = 0; i < linesVector.size(); i++) {
        Line2D.Float line2D = (Line2D.Float) linesVector.elementAt(i);
        pg2D.draw(line2D);
      }
      return Printable.PAGE_EXISTS;
    }
  }
}



Create PageFormats on a higher level

  
/**
 * 
 * JFreeReport : a free Java reporting library
 * 
 *
 * Project Info:  http://reporting.pentaho.org/
 *
 * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
 *
 * This library is free software; you can redistribute it and/or modify it under the terms
 * of the GNU Lesser General Public License as published by the Free Software Foundation;
 * either version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with this
 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
 * in the United States and other countries.]
 *
 * ------------
 * PageFormatFactory.java
 * ------------
 * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
 */
import java.awt.Insets;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.lang.reflect.Field;
import sun.rmi.runtime.Log;

/**
 * The PageFormatFactory is used to create PageFormats on a higher level. The Factory contains templates for all
 * PageSizes defined by Adobe:
 * <p/>
 * 
 * <p/>
 * Usage for creating an printjob on A4 paper with 2.5 cm border:
 * <pre>
 * Paper paper = PageFormatFactory.createPaper (PageSize.A4);
 * PageFormatFactory.setBordersMm (paper, 25, 25, 25, 25);
 * PageFormat format = PageFormatFactory.createPageFormat (paper, PageFormat.PORTRAIT);
 * </code>
 * <p/>
 * Defining a pageformat can be an ugly task and full of dependencies. The call to
 * PageFormatFactory.setBorders(...) will setup the paper"s border and always assumes
 * that the paper is laid out in Portrait.
 * <p/>
 * Changing the PageFormat"s orientation does not change the PageFormat"s paper object,
 * but it changes the way, how the paper object is interpreted.
 *
 * @author Thomas Morgner
 */
public final class PageFormatFactory
{
  /**
   * Constant for dots per inch.
   *
   * @deprecated Not used anywhere.
   */
  public static final int DOTS_PER_INCH = 72;
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] PAPER11X17 = {792, 1224};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] PAPER10X11 = {720, 792};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] PAPER10X13 = {720, 936};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] PAPER10X14 = {720, 1008};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] PAPER12X11 = {864, 792};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] PAPER15X11 = {1080, 792};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] PAPER7X9 = {504, 648};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] PAPER8X10 = {576, 720};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] PAPER9X11 = {648, 792};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] PAPER9X12 = {648, 864};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] A0 = {2384, 3370};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] A1 = {1684, 2384};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] A2 = {1191, 1684};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] A3 = {842, 1191};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] A3_TRANSVERSE = {842, 1191};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] A3_EXTRA = {913, 1262};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] A3_EXTRATRANSVERSE = {913, 1262};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] A3_ROTATED = {1191, 842};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] A4 = {595, 842};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] A4_TRANSVERSE = {595, 842};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] A4_EXTRA = {667, 914};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] A4_PLUS = {595, 936};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] A4_ROTATED = {842, 595};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] A4_SMALL = {595, 842};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] A5 = {420, 595};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] A5_TRANSVERSE = {420, 595};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] A5_EXTRA = {492, 668};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] A5_ROTATED = {595, 420};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] A6 = {297, 420};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] A6_ROTATED = {420, 297};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] A7 = {210, 297};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] A8 = {148, 210};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] A9 = {105, 148};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] A10 = {73, 105};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ANSIC = {1224, 1584};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ANSID = {1584, 2448};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ANSIE = {2448, 3168};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ARCHA = {648, 864};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ARCHB = {864, 1296};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ARCHC = {1296, 1728};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ARCHD = {1728, 2592};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ARCHE = {2592, 3456};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] B0 = {2920, 4127};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] B1 = {2064, 2920};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] B2 = {1460, 2064};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] B3 = {1032, 1460};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] B4 = {729, 1032};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] B4_ROTATED = {1032, 729};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] B5 = {516, 729};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] B5_TRANSVERSE = {516, 729};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] B5_ROTATED = {729, 516};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] B6 = {363, 516};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] B6_ROTATED = {516, 363};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] B7 = {258, 363};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] B8 = {181, 258};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] B9 = {127, 181};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] B10 = {91, 127};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] C4 = {649, 918};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] C5 = {459, 649};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] C6 = {323, 459};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] COMM10 = {297, 684};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] DL = {312, 624};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] DOUBLEPOSTCARD = {567, 419};  // should be 419.5, but I ignore that..
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] DOUBLEPOSTCARD_ROTATED = {419, 567};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENV9 = {279, 639};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENV10 = {297, 684};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENV11 = {324, 747};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENV12 = {342, 792};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENV14 = {360, 828};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVC0 = {2599, 3676};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVC1 = {1837, 2599};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVC2 = {1298, 1837};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVC3 = {918, 1296};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVC4 = {649, 918};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVC5 = {459, 649};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVC6 = {323, 459};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVC65 = {324, 648};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVC7 = {230, 323};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVCHOU3 = {340, 666};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVCHOU3_ROTATED = {666, 340};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVCHOU4 = {255, 581};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVCHOU4_ROTATED = {581, 255};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVDL = {312, 624};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVINVITE = {624, 624};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVISOB4 = {708, 1001};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVISOB5 = {499, 709};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVISOB6 = {499, 354};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVITALIAN = {312, 652};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVELOPE = {312, 652};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVKAKU2 = {680, 941};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVKAKU2_ROTATED = {941, 680};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVKAKU3 = {612, 785};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVKAKU3_ROTATED = {785, 612};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVMONARCH = {279, 540};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVPERSONAL = {261, 468};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVPRC1 = {289, 468};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVPRC1_ROTATED = {468, 289};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVPRC2 = {289, 499};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVPRC2_ROTATED = {499, 289};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVPRC3 = {354, 499};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVPRC3_ROTATED = {499, 354};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVPRC4 = {312, 590};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVPRC4_ROTATED = {590, 312};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVPRC5 = {312, 624};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVPRC5_ROTATED = {624, 312};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVPRC6 = {340, 652};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVPRC6_ROTATED = {652, 340};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVPRC7 = {454, 652};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVPRC7_ROTATED = {652, 454};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVPRC8 = {340, 876};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVPRC8_ROTATED = {876, 340};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVPRC9 = {649, 918};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVPRC9_ROTATED = {918, 649};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVPRC10 = {918, 1298};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVPRC10_ROTATED = {1298, 918};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVYOU4 = {298, 666};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ENVYOU4_ROTATED = {666, 298};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] EXECUTIVE = {522, 756};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] FANFOLDUS = {1071, 792};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] FANFOLDGERMAN = {612, 864};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] FANFOLDGERMANLEGAL = {612, 936};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] FOLIO = {595, 935};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ISOB0 = {2835, 4008};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ISOB1 = {2004, 2835};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ISOB2 = {1417, 2004};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ISOB3 = {1001, 1417};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ISOB4 = {709, 1001};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ISOB5 = {499, 709};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ISOB5_EXTRA = {570, 782};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ISOB6 = {354, 499};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ISOB7 = {249, 354};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ISOB8 = {176, 249};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ISOB9 = {125, 176};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] ISOB10 = {88, 125};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] LEDGER = {1224, 792};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] LEGAL = {612, 1008};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] LEGAL_EXTRA = {684, 1080};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] LETTER = {612, 792};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] LETTER_TRANSVERSE = {612, 792};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] LETTER_EXTRA = {684, 864};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] LETTER_EXTRATRANSVERSE = {684, 864};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] LETTER_PLUS = {612, 914};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] LETTER_ROTATED = {792, 612};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] LETTER_SMALL = {612, 792};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] MONARCH = ENVMONARCH;
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] NOTE = {612, 792};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] POSTCARD = {284, 419};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] POSTCARD_ROTATED = {419, 284};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] PRC16K = {414, 610};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] PRC16K_ROTATED = {610, 414};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] PRC32K = {275, 428};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] PRC32K_ROTATED = {428, 275};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] PRC32K_BIG = {275, 428};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] PRC32K_BIGROTATED = {428, 275};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] QUARTO = {610, 780};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] STATEMENT = {396, 612};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] SUPERA = {643, 1009};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] SUPERB = {864, 1380};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] TABLOID = {792, 1224};
  /**
   * A standard paper size.
   *
   * @deprecated Using public static arrays is dangerous.
   */
  public static final int[] TABLOIDEXTRA = {864, 1296};
  /**
   * A single instance of the factory.
   */
  private static PageFormatFactory singleton;
  /**
   * Default constructor.
   */
  private PageFormatFactory()
  {
  }
  /**
   * Returns a single instance of the factory.
   *
   * @return an instance of a PageFormatFactory.
   */
  public static PageFormatFactory getInstance()
  {
    if (singleton == null)
    {
      singleton = new PageFormatFactory();
    }
    return singleton;
  }
  /**
   * Creates a paper by using the paper size in points found in the int-array. The array must have a length of 2 and the
   * first value of this array has to contain the width and the second the height parameter. The created Paper has no
   * ImagableArea defined.
   *
   * @param papersize the definition of the papersize in a 2-element int-array
   * @return the created paper
   */
  public Paper createPaper(final int[] papersize)
  {
    if (papersize.length != 2)
    {
      throw new IllegalArgumentException("Paper must have a width and a height");
    }
    return createPaper(papersize[0], papersize[1]);
  }
  /**
   * Creates a paper by using the paper size in points found in the int-array. The array must have a length of 2 and the
   * first value of this array has to contain the width and the second the height parameter. The created Paper has no
   * ImagableArea defined.
   *
   * @param papersize the definition of the papersize in a 2-element int-array
   * @return the created paper
   */
  public Paper createPaper(final PageSize papersize)
  {
    return createPaper(papersize.getWidth(), papersize.getHeight());
  }
  /**
   * Creates a paper by using the paper size in points. The created Paper has no ImagableArea defined.
   *
   * @param width  the width of the paper in points
   * @param height the height of the paper in points
   * @return the created paper
   * @deprecated Use the double version instead.
   */
  public Paper createPaper(final int width, final int height)
  {
    return createPaper((double) width, (double) height);
  }
  /**
   * Creates a paper by using the paper size in points. The created Paper has no ImagableArea defined.
   *
   * @param width  the width of the paper in points
   * @param height the height of the paper in points
   * @return the created paper
   */
  public Paper createPaper(final double width, final double height)
  {
    final Paper p = new Paper();
    p.setSize(width, height);
    setBorders(p, 0, 0, 0, 0);
    return p;
  }
  /**
   * Defines the imageable area of the given paper by adjusting the border around the imagable area. The bordersizes are
   * given in points.
   *
   * @param paper  the paper that should be modified
   * @param top    the bordersize of the top-border
   * @param left   the border in points in the left
   * @param bottom the border in points in the bottom
   * @param right  the border in points in the right
   */
  public void setBorders(final Paper paper, final double top,
                         final double left, final double bottom, final double right)
  {
    final double w = paper.getWidth() - (right + left);
    final double h = paper.getHeight() - (bottom + top);
    paper.setImageableArea(left, top, w, h);
  }
  /**
   * Defines the imageable area of the given paper by adjusting the border around the imagable area. The bordersizes are
   * given in inches.
   *
   * @param paper  the paper that should be modified
   * @param top    the bordersize of the top-border
   * @param left   the border in points in the left
   * @param bottom the border in points in the bottom
   * @param right  the border in points in the right
   */
  public void setBordersInch
      (final Paper paper, final double top, final double left,
       final double bottom, final double right)
  {
    setBorders(paper, convertInchToPoints(top), convertInchToPoints(left),
        convertInchToPoints(bottom), convertInchToPoints(right));
  }
  /**
   * Defines the imageable area of the given paper by adjusting the border around the imagable area. The bordersizes are
   * given in millimeters.
   *
   * @param paper  the paper that should be modified
   * @param top    the bordersize of the top-border
   * @param left   the border in points in the left
   * @param bottom the border in points in the bottom
   * @param right  the border in points in the right
   */
  public void setBordersMm
      (final Paper paper, final double top, final double left,
       final double bottom, final double right)
  {
    setBorders(paper, convertMmToPoints(top), convertMmToPoints(left),
        convertMmToPoints(bottom), convertMmToPoints(right));
  }
  /**
   * Converts the given inch value to a valid point-value.
   *
   * @param inches the size in inch
   * @return the size in points
   */
  public double convertInchToPoints(final double inches)
  {
    return inches * 72.0f;
  }
  /**
   * Converts the given millimeter value to a valid point-value.
   *
   * @param mm the size in inch
   * @return the size in points
   */
  public double convertMmToPoints(final double mm)
  {
    return mm * (72.0d / 254.0d) * 10;
  }
  /**
   * Creates a new pageformat using the given paper and the given orientation.
   *
   * @param paper       the paper to use in the new pageformat
   * @param orientation one of PageFormat.PORTRAIT, PageFormat.LANDSCAPE or PageFormat.REVERSE_LANDSCAPE
   * @return the created Pageformat
   * @throws NullPointerException if the paper given was null
   */
  public PageFormat createPageFormat(final Paper paper, final int orientation)
  {
    if (paper == null)
    {
      throw new NullPointerException("Paper given must not be null");
    }
    final PageFormat pf = new PageFormat();
    pf.setPaper(paper);
    pf.setOrientation(orientation);
    return pf;
  }
  /**
   * Creates a paper by looking up the given Uppercase name in this classes defined constants. The value if looked up by
   * introspection, if the value is not defined in this class, null is returned.
   *
   * @param name the name of the constant defining the papersize
   * @return the defined paper or null, if the name was invalid.
   */
  public Paper createPaper(final String name)
  {
    try
    {
      final Field f = PageSize.class.getDeclaredField(name);
      final Object o = f.get(null);
      if (o instanceof PageSize == false)
      {
        // Log.debug ("Is no valid pageformat definition");
        return null;
      }
      final PageSize pageformat = (PageSize) o;
      return createPaper(pageformat);
    }
    catch (NoSuchFieldException nfe)
    {
      // Log.debug ("There is no pageformat " + name + " defined.");
      return null;
    }
    catch (IllegalAccessException aie)
    {
      // Log.debug ("There is no pageformat " + name + " accessible.");
      return null;
    }
  }
  /**
   * Logs the page format.
   *
   * @param pf the page format.
   */
  public static void logPageFormat(final PageFormat pf)
  {
    System.out.println("PageFormat: Width: " + pf.getWidth() + " Height: " + pf.getHeight());
    System.out.println("PageFormat: Image: X " + pf.getImageableX()
        + " Y " + pf.getImageableY()
        + " W: " + pf.getImageableWidth()
        + " H: " + pf.getImageableHeight());
    System.out.println("PageFormat: Margins: X " + pf.getImageableX()
        + " Y " + pf.getImageableY()
        + " X2: " + (pf.getImageableWidth() + pf.getImageableX())
        + " Y2: " + (pf.getImageableHeight() + pf.getImageableY()));
  }
  /**
   * Logs the paper size.
   *
   * @param pf the paper size.
   */
  public static void logPaper(final Paper pf)
  {
    System.out.println("Paper: Width: " + pf.getWidth() + " Height: " + pf.getHeight());
    System.out.println("Paper: Image: X " + pf.getImageableX()
        + " Y " + pf.getImageableY()
        + " H: " + pf.getImageableHeight()
        + " W: " + pf.getImageableWidth());
  }
  /**
   * Tests, whether the given two page format objects are equal.
   *
   * @param pf1 the first page format that should be compared.
   * @param pf2 the second page format that should be compared.
   * @return true, if both page formats are equal, false otherwise.
   */
  public static boolean isEqual(final PageFormat pf1, final PageFormat pf2)
  {
    if (pf1 == pf2)
    {
      return true;
    }
    if (pf1 == null || pf2 == null)
    {
      return false;
    }
    if (pf1.getOrientation() != pf2.getOrientation())
    {
      return false;
    }
    final Paper p1 = pf1.getPaper();
    final Paper p2 = pf2.getPaper();
    if (p1.getWidth() != p2.getWidth())
    {
      return false;
    }
    if (p1.getHeight() != p2.getHeight())
    {
      return false;
    }
    if (p1.getImageableX() != p2.getImageableX())
    {
      return false;
    }
    if (p1.getImageableY() != p2.getImageableY())
    {
      return false;
    }
    if (p1.getImageableWidth() != p2.getImageableWidth())
    {
      return false;
    }
    if (p1.getImageableHeight() != p2.getImageableHeight())
    {
      return false;
    }
    return true;
  }
  /**
   * Returns the left border of the given paper.
   *
   * @param p the paper that defines the borders.
   * @return the left border.
   */
  public double getLeftBorder(final Paper p)
  {
    return p.getImageableX();
  }
  /**
   * Returns the right border of the given paper.
   *
   * @param p the paper that defines the borders.
   * @return the right border.
   */
  public double getRightBorder(final Paper p)
  {
    return p.getWidth() - (p.getImageableX() + p.getImageableWidth());
  }
  /**
   * Returns the top border of the given paper.
   *
   * @param p the paper that defines the borders.
   * @return the top border.
   */
  public double getTopBorder(final Paper p)
  {
    return p.getImageableY();
  }
  /**
   * Returns the bottom border of the given paper.
   *
   * @param p the paper that defines the borders.
   * @return the bottom border.
   */
  public double getBottomBorder(final Paper p)
  {
    return p.getHeight() - (p.getImageableY() + p.getImageableHeight());
  }
  /**
   * Resolves a page format, so that the result can be serialized.
   *
   * @param format the page format that should be prepared for serialisation.
   * @return the prepared page format data.
   * @deprecated This functionality is part of JCommon-Serializer
   */
  public Object[] resolvePageFormat(final PageFormat format)
  {
    final Integer orientation = new Integer(format.getOrientation());
    final Paper p = format.getPaper();
    final float[] fdim = new float[]{(float) p.getWidth(), (float) p.getHeight()};
    final float[] rect = new float[]{(float) p.getImageableX(),
        (float) p.getImageableY(),
        (float) p.getImageableWidth(),
        (float) p.getImageableHeight()};
    return new Object[]{orientation, fdim, rect};
  }
  /**
   * Restores a page format after it has been serialized.
   *
   * @param data the serialized page format data.
   * @return the restored page format.
   * @deprecated This functionality is part of JCommon-Serializer
   */
  public PageFormat createPageFormat(final Object[] data)
  {
    final Integer orientation = (Integer) data[0];
    final float[] dim = (float[]) data[1];
    final float[] rect = (float[]) data[2];
    final Paper p = new Paper();
    p.setSize(dim[0], dim[1]);
    p.setImageableArea(rect[0], rect[1], rect[2], rect[3]);
    final PageFormat format = new PageFormat();
    format.setPaper(p);
    format.setOrientation(orientation.intValue());
    return format;
  }
  public Insets getPageMargins (final PageFormat format)
  {
    final int marginLeft = (int) format.getImageableX();
    final int marginRight = (int)
                (format.getWidth() - format.getImageableWidth() - format.getImageableX());
    final int marginTop = (int) (format.getImageableY());
    final int marginBottom = (int)
                (format.getHeight() - format.getImageableHeight() - format.getImageableY());
    return new Insets(marginTop, marginLeft, marginBottom, marginRight);
  }
}
/**
 * 
 * JFreeReport : a free Java reporting library
 * 
 *
 * Project Info:  http://reporting.pentaho.org/
 *
 * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
 *
 * This library is free software; you can redistribute it and/or modify it under the terms
 * of the GNU Lesser General Public License as published by the Free Software Foundation;
 * either version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with this
 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
 * in the United States and other countries.]
 *
 * ------------
 * PageSize.java
 * ------------
 * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
 */

/**
 * A class defining a page-dimension.
 *
 * @author Thomas Morgner
 */
final class PageSize
{
  /**
   * A standard paper size.
   */
  public static final PageSize PAPER11X17 = new PageSize(792, 1224);
  /**
   * A standard paper size.
   */
  public static final PageSize PAPER10X11 = new PageSize(720, 792);
  /**
   * A standard paper size.
   */
  public static final PageSize PAPER10X13 = new PageSize(720, 936);
  /**
   * A standard paper size.
   */
  public static final PageSize PAPER10X14 = new PageSize(720, 1008);
  /**
   * A standard paper size.
   */
  public static final PageSize PAPER12X11 = new PageSize(864, 792);
  /**
   * A standard paper size.
   */
  public static final PageSize PAPER15X11 = new PageSize(1080, 792);
  /**
   * A standard paper size.
   */
  public static final PageSize PAPER7X9 = new PageSize(504, 648);
  /**
   * A standard paper size.
   */
  public static final PageSize PAPER8X10 = new PageSize(576, 720);
  /**
   * A standard paper size.
   */
  public static final PageSize PAPER9X11 = new PageSize(648, 792);
  /**
   * A standard paper size.
   */
  public static final PageSize PAPER9X12 = new PageSize(648, 864);
  /**
   * A standard paper size.
   */
  public static final PageSize A0 = new PageSize(2384, 3370);
  /**
   * A standard paper size.
   */
  public static final PageSize A1 = new PageSize(1684, 2384);
  /**
   * A standard paper size.
   */
  public static final PageSize A2 = new PageSize(1191, 1684);
  /**
   * A standard paper size.
   */
  public static final PageSize A3 = new PageSize(842, 1191);
  /**
   * A standard paper size.
   */
  public static final PageSize A3_TRANSVERSE = new PageSize(842, 1191);
  /**
   * A standard paper size.
   */
  public static final PageSize A3_EXTRA = new PageSize(913, 1262);
  /**
   * A standard paper size.
   */
  public static final PageSize A3_EXTRATRANSVERSE = new PageSize(913, 1262);
  /**
   * A standard paper size.
   */
  public static final PageSize A3_ROTATED = new PageSize(1191, 842);
  /**
   * A standard paper size.
   */
  public static final PageSize A4 = new PageSize(595, 842);
  /**
   * A standard paper size.
   */
  public static final PageSize A4_TRANSVERSE = new PageSize(595, 842);
  /**
   * A standard paper size.
   */
  public static final PageSize A4_EXTRA = new PageSize(667, 914);
  /**
   * A standard paper size.
   */
  public static final PageSize A4_PLUS = new PageSize(595, 936);
  /**
   * A standard paper size.
   */
  public static final PageSize A4_ROTATED = new PageSize(842, 595);
  /**
   * A standard paper size.
   */
  public static final PageSize A4_SMALL = new PageSize(595, 842);
  /**
   * A standard paper size.
   */
  public static final PageSize A5 = new PageSize(420, 595);
  /**
   * A standard paper size.
   */
  public static final PageSize A5_TRANSVERSE = new PageSize(420, 595);
  /**
   * A standard paper size.
   */
  public static final PageSize A5_EXTRA = new PageSize(492, 668);
  /**
   * A standard paper size.
   */
  public static final PageSize A5_ROTATED = new PageSize(595, 420);
  /**
   * A standard paper size.
   */
  public static final PageSize A6 = new PageSize(297, 420);
  /**
   * A standard paper size.
   */
  public static final PageSize A6_ROTATED = new PageSize(420, 297);
  /**
   * A standard paper size.
   */
  public static final PageSize A7 = new PageSize(210, 297);
  /**
   * A standard paper size.
   */
  public static final PageSize A8 = new PageSize(148, 210);
  /**
   * A standard paper size.
   */
  public static final PageSize A9 = new PageSize(105, 148);
  /**
   * A standard paper size.
   */
  public static final PageSize A10 = new PageSize(73, 105);
  /**
   * A standard paper size.
   */
  public static final PageSize ANSIC = new PageSize(1224, 1584);
  /**
   * A standard paper size.
   */
  public static final PageSize ANSID = new PageSize(1584, 2448);
  /**
   * A standard paper size.
   */
  public static final PageSize ANSIE = new PageSize(2448, 3168);
  /**
   * A standard paper size.
   */
  public static final PageSize ARCHA = new PageSize(648, 864);
  /**
   * A standard paper size.
   */
  public static final PageSize ARCHB = new PageSize(864, 1296);
  /**
   * A standard paper size.
   */
  public static final PageSize ARCHC = new PageSize(1296, 1728);
  /**
   * A standard paper size.
   */
  public static final PageSize ARCHD = new PageSize(1728, 2592);
  /**
   * A standard paper size.
   */
  public static final PageSize ARCHE = new PageSize(2592, 3456);
  /**
   * A standard paper size.
   */
  public static final PageSize B0 = new PageSize(2920, 4127);
  /**
   * A standard paper size.
   */
  public static final PageSize B1 = new PageSize(2064, 2920);
  /**
   * A standard paper size.
   */
  public static final PageSize B2 = new PageSize(1460, 2064);
  /**
   * A standard paper size.
   */
  public static final PageSize B3 = new PageSize(1032, 1460);
  /**
   * A standard paper size.
   */
  public static final PageSize B4 = new PageSize(729, 1032);
  /**
   * A standard paper size.
   */
  public static final PageSize B4_ROTATED = new PageSize(1032, 729);
  /**
   * A standard paper size.
   */
  public static final PageSize B5 = new PageSize(516, 729);
  /**
   * A standard paper size.
   */
  public static final PageSize B5_TRANSVERSE = new PageSize(516, 729);
  /**
   * A standard paper size.
   */
  public static final PageSize B5_ROTATED = new PageSize(729, 516);
  /**
   * A standard paper size.
   */
  public static final PageSize B6 = new PageSize(363, 516);
  /**
   * A standard paper size.
   */
  public static final PageSize B6_ROTATED = new PageSize(516, 363);
  /**
   * A standard paper size.
   */
  public static final PageSize B7 = new PageSize(258, 363);
  /**
   * A standard paper size.
   */
  public static final PageSize B8 = new PageSize(181, 258);
  /**
   * A standard paper size.
   */
  public static final PageSize B9 = new PageSize(127, 181);
  /**
   * A standard paper size.
   */
  public static final PageSize B10 = new PageSize(91, 127);
  /**
   * A standard paper size.
   */
  public static final PageSize C4 = new PageSize(649, 918);
  /**
   * A standard paper size.
   */
  public static final PageSize C5 = new PageSize(459, 649);
  /**
   * A standard paper size.
   */
  public static final PageSize C6 = new PageSize(323, 459);
  /**
   * A standard paper size.
   */
  public static final PageSize COMM10 = new PageSize(297, 684);
  /**
   * A standard paper size.
   */
  public static final PageSize DL = new PageSize(312, 624);
  /**
   * A standard paper size.
   */
  public static final PageSize DOUBLEPOSTCARD = new PageSize(567, 419);  // should be 419.5, but I ignore that..
  /**
   * A standard paper size.
   */
  public static final PageSize DOUBLEPOSTCARD_ROTATED = new PageSize(419, 567);
  /**
   * A standard paper size.
   */
  public static final PageSize ENV9 = new PageSize(279, 639);
  /**
   * A standard paper size.
   */
  public static final PageSize ENV10 = new PageSize(297, 684);
  /**
   * A standard paper size.
   */
  public static final PageSize ENV11 = new PageSize(324, 747);
  /**
   * A standard paper size.
   */
  public static final PageSize ENV12 = new PageSize(342, 792);
  /**
   * A standard paper size.
   */
  public static final PageSize ENV14 = new PageSize(360, 828);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVC0 = new PageSize(2599, 3676);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVC1 = new PageSize(1837, 2599);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVC2 = new PageSize(1298, 1837);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVC3 = new PageSize(918, 1296);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVC4 = new PageSize(649, 918);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVC5 = new PageSize(459, 649);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVC6 = new PageSize(323, 459);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVC65 = new PageSize(324, 648);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVC7 = new PageSize(230, 323);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVCHOU3 = new PageSize(340, 666);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVCHOU3_ROTATED = new PageSize(666, 340);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVCHOU4 = new PageSize(255, 581);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVCHOU4_ROTATED = new PageSize(581, 255);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVDL = new PageSize(312, 624);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVINVITE = new PageSize(624, 624);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVISOB4 = new PageSize(708, 1001);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVISOB5 = new PageSize(499, 709);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVISOB6 = new PageSize(499, 354);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVITALIAN = new PageSize(312, 652);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVELOPE = new PageSize(312, 652);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVKAKU2 = new PageSize(680, 941);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVKAKU2_ROTATED = new PageSize(941, 680);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVKAKU3 = new PageSize(612, 785);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVKAKU3_ROTATED = new PageSize(785, 612);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVMONARCH = new PageSize(279, 540);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVPERSONAL = new PageSize(261, 468);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVPRC1 = new PageSize(289, 468);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVPRC1_ROTATED = new PageSize(468, 289);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVPRC2 = new PageSize(289, 499);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVPRC2_ROTATED = new PageSize(499, 289);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVPRC3 = new PageSize(354, 499);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVPRC3_ROTATED = new PageSize(499, 354);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVPRC4 = new PageSize(312, 590);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVPRC4_ROTATED = new PageSize(590, 312);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVPRC5 = new PageSize(312, 624);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVPRC5_ROTATED = new PageSize(624, 312);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVPRC6 = new PageSize(340, 652);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVPRC6_ROTATED = new PageSize(652, 340);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVPRC7 = new PageSize(454, 652);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVPRC7_ROTATED = new PageSize(652, 454);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVPRC8 = new PageSize(340, 876);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVPRC8_ROTATED = new PageSize(876, 340);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVPRC9 = new PageSize(649, 918);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVPRC9_ROTATED = new PageSize(918, 649);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVPRC10 = new PageSize(918, 1298);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVPRC10_ROTATED = new PageSize(1298, 918);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVYOU4 = new PageSize(298, 666);
  /**
   * A standard paper size.
   */
  public static final PageSize ENVYOU4_ROTATED = new PageSize(666, 298);
  /**
   * A standard paper size.
   */
  public static final PageSize EXECUTIVE = new PageSize(522, 756);
  /**
   * A standard paper size.
   */
  public static final PageSize FANFOLDUS = new PageSize(1071, 792);
  /**
   * A standard paper size.
   */
  public static final PageSize FANFOLDGERMAN = new PageSize(612, 864);
  /**
   * A standard paper size.
   */
  public static final PageSize FANFOLDGERMANLEGAL = new PageSize(612, 936);
  /**
   * A standard paper size.
   */
  public static final PageSize FOLIO = new PageSize(595, 935);
  /**
   * A standard paper size.
   */
  public static final PageSize ISOB0 = new PageSize(2835, 4008);
  /**
   * A standard paper size.
   */
  public static final PageSize ISOB1 = new PageSize(2004, 2835);
  /**
   * A standard paper size.
   */
  public static final PageSize ISOB2 = new PageSize(1417, 2004);
  /**
   * A standard paper size.
   */
  public static final PageSize ISOB3 = new PageSize(1001, 1417);
  /**
   * A standard paper size.
   */
  public static final PageSize ISOB4 = new PageSize(709, 1001);
  /**
   * A standard paper size.
   */
  public static final PageSize ISOB5 = new PageSize(499, 709);
  /**
   * A standard paper size.
   */
  public static final PageSize ISOB5_EXTRA = new PageSize(570, 782);
  /**
   * A standard paper size.
   */
  public static final PageSize ISOB6 = new PageSize(354, 499);
  /**
   * A standard paper size.
   */
  public static final PageSize ISOB7 = new PageSize(249, 354);
  /**
   * A standard paper size.
   */
  public static final PageSize ISOB8 = new PageSize(176, 249);
  /**
   * A standard paper size.
   */
  public static final PageSize ISOB9 = new PageSize(125, 176);
  /**
   * A standard paper size.
   */
  public static final PageSize ISOB10 = new PageSize(88, 125);
  /**
   * A standard paper size.
   */
  public static final PageSize LEDGER = new PageSize(1224, 792);
  /**
   * A standard paper size.
   */
  public static final PageSize LEGAL = new PageSize(612, 1008);
  /**
   * A standard paper size.
   */
  public static final PageSize LEGAL_EXTRA = new PageSize(684, 1080);
  /**
   * A standard paper size.
   */
  public static final PageSize LETTER = new PageSize(612, 792);
  /**
   * A standard paper size.
   */
  public static final PageSize LETTER_TRANSVERSE = new PageSize(612, 792);
  /**
   * A standard paper size.
   */
  public static final PageSize LETTER_EXTRA = new PageSize(684, 864);
  /**
   * A standard paper size.
   */
  public static final PageSize LETTER_EXTRATRANSVERSE = new PageSize(684, 864);
  /**
   * A standard paper size.
   */
  public static final PageSize LETTER_PLUS = new PageSize(612, 914);
  /**
   * A standard paper size.
   */
  public static final PageSize LETTER_ROTATED = new PageSize(792, 612);
  /**
   * A standard paper size.
   */
  public static final PageSize LETTER_SMALL = new PageSize(612, 792);
  /**
   * A standard paper size.
   */
  public static final PageSize MONARCH = ENVMONARCH;
  /**
   * A standard paper size.
   */
  public static final PageSize NOTE = new PageSize(612, 792);
  /**
   * A standard paper size.
   */
  public static final PageSize POSTCARD = new PageSize(284, 419);
  /**
   * A standard paper size.
   */
  public static final PageSize POSTCARD_ROTATED = new PageSize(419, 284);
  /**
   * A standard paper size.
   */
  public static final PageSize PRC16K = new PageSize(414, 610);
  /**
   * A standard paper size.
   */
  public static final PageSize PRC16K_ROTATED = new PageSize(610, 414);
  /**
   * A standard paper size.
   */
  public static final PageSize PRC32K = new PageSize(275, 428);
  /**
   * A standard paper size.
   */
  public static final PageSize PRC32K_ROTATED = new PageSize(428, 275);
  /**
   * A standard paper size.
   */
  public static final PageSize PRC32K_BIG = new PageSize(275, 428);
  /**
   * A standard paper size.
   */
  public static final PageSize PRC32K_BIGROTATED = new PageSize(428, 275);
  /**
   * A standard paper size.
   */
  public static final PageSize QUARTO = new PageSize(610, 780);
  /**
   * A standard paper size.
   */
  public static final PageSize STATEMENT = new PageSize(396, 612);
  /**
   * A standard paper size.
   */
  public static final PageSize SUPERA = new PageSize(643, 1009);
  /**
   * A standard paper size.
   */
  public static final PageSize SUPERB = new PageSize(864, 1380);
  /**
   * A standard paper size.
   */
  public static final PageSize TABLOID = new PageSize(792, 1224);
  /**
   * A standard paper size.
   */
  public static final PageSize TABLOIDEXTRA = new PageSize(864, 1296);
  /**
   * The width of the page in point.
   */
  private double width;
  /**
   * The height of the page in point.
   */
  private double height;
  /**
   * Creates a new page-size object with the given width and height.
   *
   * @param width  the width in point.
   * @param height the height in point.
   */
  public PageSize(final double width, final double height)
  {
    this.width = width;
    this.height = height;
  }
  /**
   * Returns the page"s width.
   *
   * @return the width in point.
   */
  public double getWidth()
  {
    return width;
  }
  /**
   * Returns the page"s height.
   *
   * @return the height in point.
   */
  public double getHeight()
  {
    return height;
  }
  /**
   * Compares this page size with the given object.
   *
   * @param o the other object.
   * @return true, if the given object is also a PageSize object and has the same width and height, false otherwise.
   */
  public boolean equals(final Object o)
  {
    if (this == o)
    {
      return true;
    }
    if (o == null || getClass() != o.getClass())
    {
      return false;
    }
    final PageSize pageSize = (PageSize) o;

    if (equal(pageSize.height, height) == false)
    {
      return false;
    }
    if (equal(pageSize.width, width) == false)
    {
      return false;
    }
    return true;
  }
  /**
   * An internal helper method that compares two doubles for equality.
   * @param d1 the one double.
   * @param d2 the other double.
   * @return true, if both doubles are binary equal, false otherwise.
   */
  private boolean equal(final double d1, final double d2)
  {
    return Double.doubleToLongBits(d1) == Double.doubleToLongBits(d2);
  }
  /**
   * Computes a hashcode for this page-size.
   *
   * @return the hashcode.
   */
  public int hashCode()
  {
    long temp = width != +0.0d ? Double.doubleToLongBits(width) : 0L;
    int result = (int) (temp ^ (temp >>> 32));
    temp = height != +0.0d ? Double.doubleToLongBits(height) : 0L;
    result = 29 * result + (int) (temp ^ (temp >>> 32));
    return result;
  }
}



Displaying the Page Format Dialog: changes the default page format such as orientation and paper size.

   
import java.awt.print.PageFormat;
import java.awt.print.PrinterJob;
public class Main {
  public static void main(String[] argv) throws Exception {
    PrinterJob pjob = PrinterJob.getPrinterJob();
    PageFormat pf = pjob.defaultPage();
    pf.setOrientation(PageFormat.LANDSCAPE);
    pf = pjob.pageDialog(pf);
  }
}



Display the print dialog and print

   
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 PrintableDemo1 implements Printable {
  public int print(Graphics g, PageFormat pf, int pageIndex) {
    if (pageIndex != 0)
      return NO_SUCH_PAGE;
    Graphics2D g2 = (Graphics2D) g;
    g2.setFont(new Font("Serif", Font.PLAIN, 36));
    g2.setPaint(Color.black);
    g2.drawString("Java Source and Support!", 144, 144);
    return PAGE_EXISTS;
  }
  public static void main(String[] args) {
    PrinterJob pj = PrinterJob.getPrinterJob();
    pj.setPrintable(new PrintableDemo1());
    if (pj.printDialog()) {
      try {
        pj.print();
      } catch (PrinterException e) {
        System.out.println(e);
      }
    }
  }
}



Listening for Print Service Status Changes

   
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.Attribute;
import javax.print.event.PrintServiceAttributeEvent;
import javax.print.event.PrintServiceAttributeListener;
public class Main {
  public static void main(String[] argv) throws Exception {
    PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
    for (int i = 0; i < services.length; i++) {
      services[i].addPrintServiceAttributeListener(new MyPrintServiceAttributeListener());
    }
  }
}
class MyPrintServiceAttributeListener implements PrintServiceAttributeListener {
  public void attributeUpdate(PrintServiceAttributeEvent psae) {
    PrintService service = psae.getPrintService();
    Attribute[] attrs = psae.getAttributes().toArray();
    for (int i = 0; i < attrs.length; i++) {
      String attrName = attrs[i].getName();
      String attrValue = attrs[i].toString();
    }
  }
}



Overriding the Default Action of a JTextComponent

   
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JTextArea;
import javax.swing.text.JTextComponent;
import javax.swing.text.Keymap;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTextArea component = new JTextArea();
    Action defAction = findDefaultAction(component);
    component.getKeymap().setDefaultAction(new MyDefaultAction(defAction));
  }
  public static Action findDefaultAction(JTextComponent c) {
    Keymap kmap = c.getKeymap();
    if (kmap.getDefaultAction() != null) {
      return kmap.getDefaultAction();
    }
    kmap = kmap.getResolveParent();
    while (kmap != null) {
      if (kmap.getDefaultAction() != null) {
        return kmap.getDefaultAction();
      }
      kmap = kmap.getResolveParent();
    }
    return null;
  }
}
class MyDefaultAction extends AbstractAction {
  Action defAction;
  public MyDefaultAction(Action a) {
    super("My Default Action");
    defAction = a;
  }
  public void actionPerformed(ActionEvent e) {
    if (e.getActionCommand() != null) {
      String command = e.getActionCommand();
      if (command != null) {
        command = command.toUpperCase();
      }
      e = new ActionEvent(e.getSource(), e.getID(), command, e.getModifiers());
    }
    if (defAction != null) {
      defAction.actionPerformed(e);
    }
  }
}



Pageable Text

   
/*
 * This example is from the book "Java Foundation Classes in a Nutshell".
 * Written by David Flanagan. Copyright (c) 1999 by O"Reilly & Associates.  
 * You may distribute this source code for non-commercial purposes only.
 * You may study, modify, and use this example for any purpose, as long as
 * this notice is retained.  Note that this example is provided "as is",
 * WITHOUT WARRANTY of any kind either expressed or implied.
 */
import java.awt.*;
import java.awt.print.*;
import java.io.*;
import java.util.Vector;
public class PageableText implements Pageable, Printable {
  // Constants for font name, size, style and line spacing
  public static String FONTFAMILY = "Monospaced";
  public static int FONTSIZE = 10;
  public static int FONTSTYLE = Font.PLAIN;
  public static float LINESPACEFACTOR = 1.1f;
  PageFormat format;   // The page size, margins, and orientation
  Vector lines;        // The text to be printed, broken into lines
  Font font;           // The font to print with
  int linespacing;     // How much space between lines
  int linesPerPage;    // How many lines fit on a page
  int numPages;        // How many pages required to print all lines
  int baseline = -1;   // The baseline position of the font.
  /** Create a PageableText object for a string of text */
  public PageableText(String text, PageFormat format) throws IOException { 
    this(new StringReader(text), format); 
  }
  /** Create a PageableText object for a file of text */
  public PageableText(File file, PageFormat format) throws IOException { 
    this(new FileReader(file), format); 
  }
  /** Create a PageableText object for a stream of text */
  public PageableText(Reader stream, PageFormat format) throws IOException {
    this.format = format;
    // First, read all the text, breaking it into lines.
    // This code ignores tabs, and does not wrap long lines.
    BufferedReader in = new BufferedReader(stream);
    lines = new Vector();
    String line;
    while((line = in.readLine()) != null) 
      lines.addElement(line);
    // Create the font we will use, and compute spacing between lines
    font = new Font(FONTFAMILY, FONTSTYLE, FONTSIZE);
    linespacing = (int) (FONTSIZE * LINESPACEFACTOR);
    // Figure out how many lines per page, and how many pages
    linesPerPage = (int)Math.floor(format.getImageableHeight()/linespacing);
    numPages = (lines.size()-1)/linesPerPage + 1;
  }
  // These are the methods of the Pageable interface.
  // Note that the getPrintable() method returns this object, which means
  // that this class must also implement the Printable interface.
  public int getNumberOfPages() { return numPages; }
  public PageFormat getPageFormat(int pagenum) { return format; }
  public Printable getPrintable(int pagenum) { return this; }
  /**
   * This is the print() method of the Printable interface.
   * It does most of the printing work.
   */
  public int print(Graphics g, PageFormat format, int pagenum) {
    // Tell the PrinterJob if the page number is not a legal one.
    if ((pagenum < 0) | (pagenum >= numPages)) 
      return NO_SUCH_PAGE;
    // First time we"re called, figure out the baseline for our font.
    // We couldn"t do this earlier because we needed a Graphics object
    if (baseline == -1) {
      FontMetrics fm = g.getFontMetrics(font);
      baseline = fm.getAscent();
    }
    // Clear the background to white.  This shouldn"t be necessary, but is
    // required on some systems to workaround an implementation bug
    g.setColor(Color.white);
    g.fillRect((int)format.getImageableX(), (int)format.getImageableY(),
               (int)format.getImageableWidth(), 
               (int)format.getImageableHeight());
    // Set the font and the color we will be drawing with.
    // Note that you cannot assume that black is the default color!
    g.setFont(font);
    g.setColor(Color.black);
    // Figure out which lines of text we will print on this page
    int startLine = pagenum * linesPerPage;
    int endLine = startLine + linesPerPage - 1;
    if (endLine >= lines.size()) 
      endLine = lines.size()-1;
    // Compute the position on the page of the first line.
    int x0 = (int) format.getImageableX();
    int y0 = (int) format.getImageableY() + baseline;
    // Loop through the lines, drawing them all to the page.
    for(int i=startLine; i <= endLine; i++) {
      // Get the line
      String line = (String)lines.elementAt(i);
      // Draw the line.
      // We use the integer version of drawString(), not the Java 2D
      // version that uses floating-point coordinates. A bug in early
      // Java2 implementations prevents the Java 2D version from working.
      if (line.length() > 0) 
        g.drawString(line, x0, y0);
      // Move down the page for the next line.
      y0 += linespacing;  
    }
    // Tell the PrinterJob that we successfully printed the page.
    return PAGE_EXISTS;
  }
  /**
   * This is a test program that demonstrates the use of PageableText
   */
  public static void main(String[] args) throws IOException, PrinterException {
    // Get the PrinterJob object that coordinates everything
    PrinterJob job = PrinterJob.getPrinterJob();
    // Get the default page format, then ask the user to customize it.
    PageFormat format = job.pageDialog(job.defaultPage());
    // Create our PageableText object, and tell the PrinterJob about it
    job.setPageable(new PageableText(new File(args[0]), format));
    // Ask the user to select a printer, etc., and if not canceled, print!
    if (job.printDialog()) 
      job.print();
  }
}



Printable Component

   
/*
 * This example is from the book "Java Foundation Classes in a Nutshell".
 * Written by David Flanagan. Copyright (c) 1999 by O"Reilly & Associates.  
 * You may distribute this source code for non-commercial purposes only.
 * You may study, modify, and use this example for any purpose, as long as
 * this notice is retained.  Note that this example is provided "as is",
 * WITHOUT WARRANTY of any kind either expressed or implied.
 */
import java.awt.*;
import java.awt.print.*;
/**
 * This wrapper class encapsulates a Component and allows it to be printed
 * using the Java 2 printing API.
 */
public class PrintableComponent implements Printable {
  // The component to be printed.
  Component c;
  /** Create a PrintableComponent wrapper around a Component */
  public PrintableComponent(Component c) { this.c = c; }
  /**
   * This method is not part of the Printable interface.  It is a method
   * that sets up the PrinterJob and initiates the printing.
   */
  public void print() throws PrinterException {
    // Get the PrinterJob object
    PrinterJob job = PrinterJob.getPrinterJob();
    // Get the default page format, then allow the user to modify it
    PageFormat format = job.pageDialog(job.defaultPage());
    // Tell the PrinterJob what to print
    job.setPrintable(this, format);
    // Ask the user to confirm, and then begin the printing process
    if (job.printDialog()) 
      job.print();
  }
  /**
   * This is the "callback" method that the PrinterJob will invoke.
   * This method is defined by the Printable interface.
   */
  public int print(Graphics g, PageFormat format, int pagenum) {
    // The PrinterJob will keep trying to print pages until we return
    // this value to tell it that it has reached the end.
    if (pagenum > 0) 
      return Printable.NO_SUCH_PAGE;
    // We"re passed a Graphics object, but it can always be cast to Graphics2D
    Graphics2D g2 = (Graphics2D) g;
    // Use the top and left margins specified in the PageFormat Note
    // that the PageFormat methods are poorly named.  They specify
    // margins, not the actual imageable area of the printer.
    g2.translate(format.getImageableX(), format.getImageableY());
    // Tell the component to draw itself to the printer by passing in 
    // the Graphics2D object.  This will not work well if the component
    // has double-buffering enabled.
    c.paint(g2);
    // Return this constant to tell the PrinterJob that we printed the page.
    return Printable.PAGE_EXISTS;
  }
}



Printable demo

   
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
public class PrintableDemo implements Printable {
  public int print(Graphics g, PageFormat pf, int pageIndex) {
    if (pageIndex != 0)
      return NO_SUCH_PAGE;
    Graphics2D g2 = (Graphics2D) g;
    g2.setFont(new Font("Serif", Font.PLAIN, 36));
    g2.setPaint(Color.black);
    g2.drawString("Java Source and Support", 100, 100);
    Rectangle2D outline = new Rectangle2D.Double(pf.getImageableX(), pf
        .getImageableY(), pf.getImageableWidth(), pf
        .getImageableHeight());
    g2.draw(outline);
    return PAGE_EXISTS;
  }
  public static void main(String[] args) {
    PrinterJob pj = PrinterJob.getPrinterJob();
    PageFormat pf = pj.defaultPage();
    Paper paper = new Paper();
    double margin = 36; // half inch
    paper.setImageableArea(margin, margin, paper.getWidth() - margin * 2,
        paper.getHeight() - margin * 2);
    pf.setPaper(paper);
    pj.setPrintable(new PrintableDemo(), pf);
    if (pj.printDialog()) {
      try {
        pj.print();
      } catch (PrinterException e) {
        System.out.println(e);
      }
    }
  }
}



Printable Document

   
/*
 * Copyright (c) 2000 David Flanagan.  All rights reserved.
 * This code is from the book Java Examples in a Nutshell, 2nd 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.
 * You may distribute it non-commercially as long as you retain this notice.
 * For a commercial use license, or to purchase the book (recommended),
 * visit http://www.davidflanagan.ru/javaexamples2.
 */
import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.font.LineMetrics;
import java.awt.geom.Rectangle2D;
import java.awt.print.PageFormat;
import java.awt.print.Pageable;
import java.awt.print.Paper;
import java.awt.print.Printable;
import java.util.ArrayList;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.EditorKit;
import javax.swing.text.Element;
import javax.swing.text.JTextComponent;
import javax.swing.text.Position;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;
import PrintableDocument.ParentView;
/**
 * This class implements the Pageable and Printable interfaces and allows the
 * contents of any JTextComponent to be printed using the java.awt.print
 * printing API.
 */
public class PrintableDocument implements Pageable, Printable {
  View root; // The root View to be printed
  PageFormat format; // Paper plus page orientation
  int numPages; // How many pages in the document
  double printX, printY; // coordinates of upper-left of print area
  double printWidth; // Width of the printable area
  double printHeight; // Height of the printable area
  Rectangle drawRect; // The rectangle in which the document is painted
  // How lenient are we with the bottom margin in widow and orphan prevention?
  static final double MARGIN_ADJUST = .97;
  // The font we use for printing page numbers
  static final Font headerFont = new Font("Serif", Font.PLAIN, 12);
  /**
   * This constructor allows printing the contents of any JTextComponent using
   * a default PageFormat
   */
  public PrintableDocument(JTextComponent textComponent) {
    this(textComponent, new PageFormat());
  }
  /**
   * This constructor allows the contents of any JTextComponent to be printed,
   * using any specified PageFormat object
   */
  public PrintableDocument(JTextComponent textComponent, PageFormat format) {
    // Remember the page format, and ask it for the printable area
    this.format = format;
    this.printX = format.getImageableX();
    this.printY = format.getImageableY();
    this.printWidth = format.getImageableWidth();
    this.printHeight = format.getImageableHeight();
    double paperWidth = format.getWidth();
    // Get the document and its root Element from the text component
    Document document = textComponent.getDocument();
    Element rootElement = document.getDefaultRootElement();
    // Get the EditorKit and its ViewFactory from the text component
    EditorKit editorKit = textComponent.getUI().getEditorKit(textComponent);
    ViewFactory viewFactory = editorKit.getViewFactory();
    // Use the ViewFactory to create a root View object for the document
    // This is the object we"ll print.
    root = viewFactory.create(rootElement);
    // The Swing text architecture requires us to call setParent() on
    // our root View before we use it for anything. In order to do this,
    // we need a View object that can serve as the parent. We use a
    // custom implementation defined below.
    root.setParent(new ParentView(root, viewFactory, textComponent));
    // Tell the view how wide the page is; it has to format itself
    // to fit within this width. The height doesn"t really matter here
    root.setSize((float) printWidth, (float) printHeight);
    // Now that the view has formatted itself for the specified width,
    // Ask it how tall it is.
    double documentHeight = root.getPreferredSpan(View.Y_AXIS);
    // Set up the rectangle that tells the view where to draw itself
    // We"ll use it in other methods of this class.
    drawRect = new Rectangle((int) printX, (int) printY, (int) printWidth,
        (int) documentHeight);
    // Now if the document is taller than one page, we have to
    // figure out where the page breaks are.
    if (documentHeight > printHeight)
      paginate(root, drawRect);
    // Once we"ve broken it into pages, figure out how man pages.
    numPages = pageLengths.size() + 1;
  }
  // This is the starting offset of the page we"re currently working on
  double pageStart = 0;
  /**
   * This method loops through the children of the specified view, recursing
   * as necessary, and inserts pages breaks when needed. It makes a
   * rudimentary attempt to avoid "widows" and "orphans".
   */
  protected void paginate(View v, Rectangle2D allocation) {
    // Figure out how tall this view is, and tell it to allocate
    // that space among its children
    double myheight = v.getPreferredSpan(View.Y_AXIS);
    v.setSize((float) printWidth, (float) myheight);
    // Now loop through each of the children
    int numkids = v.getViewCount();
    for (int i = 0; i < numkids; i++) {
      View kid = v.getView(i); // this is the child we"re working with
      // Figure out its size and location
      Shape kidshape = v.getChildAllocation(i, allocation);
      if (kidshape == null)
        continue;
      Rectangle2D kidbox = kidshape.getBounds2D();
      // This is the Y coordinate of the bottom of the child
      double kidpos = kidbox.getY() + kidbox.getHeight() - pageStart;
      // If this is the first child of a group, then we want to ensure
      // that it doesn"t get left by itself at the bottom of a page.
      // I.e. we want to prevent "widows"
      if ((numkids > 1) && (i == 0)) {
        // If it is not near the end of the page, then just move
        // on to the next child
        if (kidpos < printY + printHeight * MARGIN_ADJUST)
          continue;
        // Otherwise, the child is near the bottom of the page, so
        // break the page before this child and place this child on
        // the new page.
        breakPage(kidbox.getY());
        continue;
      }
      // If this is the last child of a group, we don"t want it to
      // appear by itself at the top of a new page, so allow it to
      // squeeze past the bottom margin if necessary. This helps to
      // prevent "orphans"
      if ((numkids > 1) && (i == numkids - 1)) {
        // If it fits normally, just move on to the next one
        if (kidpos < printY + printHeight)
          continue;
        // Otherwise, if it fits with extra space, then break the
        // at the end of the group
        if (kidpos < printY + printHeight / MARGIN_ADJUST) {
          breakPage(allocation.getY() + allocation.getHeight());
          continue;
        }
      }
      // If the child is not the first or last of a group, then we use
      // the bottom margin strictly. If the child fits on the page,
      // then move on to the next child.
      if (kidpos < printY + printHeight)
        continue;
      // If we get here, the child doesn"t fit on this page. If it has
      // no children, then break the page before this child and continue.
      if (kid.getViewCount() == 0) {
        breakPage(kidbox.getY());
        continue;
      }
      // If we get here, then the child did not fit on the page, but it
      // has kids of its own, so recurse to see if any of those kids
      // will fit on the page.
      paginate(kid, kidbox);
    }
  }
  // For a document of n pages, this list stores the lengths of pages
  // 0 through n-2. The last page is assumed to have a full length
  ArrayList pageLengths = new ArrayList();
  // For a document of n pages, this list stores the starting offset of
  // pages 1 through n-1. The offset of page 0 is always 0
  ArrayList pageOffsets = new ArrayList();
  /**
   * Break a page at the specified Y coordinate. Store the necessary
   * information into the pageLengths and pageOffsets lists
   */
  void breakPage(double y) {
    double pageLength = y - pageStart - printY;
    pageStart = y - printY;
    pageLengths.add(new Double(pageLength));
    pageOffsets.add(new Double(pageStart));
  }
  /** Return the number of pages. This is a Pageable method. */
  public int getNumberOfPages() {
    return numPages;
  }
  /**
   * Return the PageFormat object for the specified page. This implementation
   * uses the computed length of the page in the returned PageFormat object.
   * The PrinterJob will use this as a clipping region, which will prevent
   * extraneous parts of the document from being drawn in the top and bottom
   * margins.
   */
  public PageFormat getPageFormat(int pagenum) {
    // On the last page, just return the user-specified page format
    if (pagenum == numPages - 1)
      return format;
    // Otherwise, look up the height of this page and return an
    // appropriate PageFormat.
    double pageLength = ((Double) pageLengths.get(pagenum)).doubleValue();
    PageFormat f = (PageFormat) format.clone();
    Paper p = f.getPaper();
    if (f.getOrientation() == PageFormat.PORTRAIT)
      p.setImageableArea(printX, printY, printWidth, pageLength);
    else
      p.setImageableArea(printY, printX, pageLength, printWidth);
    f.setPaper(p);
    return f;
  }
  /**
   * This Printable method returns the Printable object for the specified
   * page. Since this class implements both Pageable and Printable, it just
   * returns this.
   */
  public Printable getPrintable(int pagenum) {
    return this;
  }
  /**
   * This is the basic Printable method that prints a specified page
   */
  public int print(Graphics g, PageFormat format, int pageIndex) {
    // Return an error code on attempts to print past the end of the doc
    if (pageIndex >= numPages)
      return NO_SUCH_PAGE;
    // Cast the Graphics object so we can use Java2D operations
    Graphics2D g2 = (Graphics2D) g;
    // Display a page number centered in the area of the top margin.
    // Set a new clipping region so we can draw into the top margin
    // But remember the original clipping region so we can restore it
    Shape originalClip = g.getClip();
    g.setClip(new Rectangle(0, 0, (int) printWidth, (int) printY));
    // Compute the header to display, measure it, then display it
    String numString = "- " + (pageIndex + 1) + " -";
    Rectangle2D numBounds = // Get the width and height of the string
    headerFont.getStringBounds(numString, g2.getFontRenderContext());
    LineMetrics metrics = // Get the ascent and descent of the font
    headerFont.getLineMetrics(numString, g2.getFontRenderContext());
    g.setFont(headerFont); // Set the font
    g.setColor(Color.black); // Print with black ink
    g.drawString(numString, // Display the string
        (int) (printX + (printWidth - numBounds.getWidth()) / 2),
        (int) ((printY - numBounds.getHeight()) / 2 + metrics
            .getAscent()));
    g.setClip(originalClip); // Restore the clipping region
    // Figure out the staring position of the page within the document
    double pageStart = 0.0;
    if (pageIndex > 0)
      pageStart = ((Double) pageOffsets.get(pageIndex - 1)).doubleValue();
    // Scroll so that the appropriate part of the document is lined up
    // with the upper-left corner of the page
    g2.translate(0.0, -pageStart);
    // Now paint the entire document. The PrinterJob will have
    // established a clipping region, so that only the desired portion
    // of the document will actually be drawn on this sheet of paper.
    root.paint(g, drawRect);
    // Finally return a success code
    return PAGE_EXISTS;
  }
  /**
   * This inner class is a concrete implementation of View, with a couple of
   * key method implementations. An instance of this class is used as the
   * parent of the root View object we want to print
   */
  static class ParentView extends View {
    ViewFactory viewFactory; // The ViewFactory for the hierarchy of views
    Container container; // The Container for the hierarchy of views
    public ParentView(View v, ViewFactory viewFactory, Container container) {
      super(v.getElement());
      this.viewFactory = viewFactory;
      this.container = container;
    }
    // These methods return key pieces of information required by
    // the View hierarchy.
    public ViewFactory getViewFactory() {
      return viewFactory;
    }
    public Container getContainer() {
      return container;
    }
    // These methods are abstract in View, so we"ve got to provide
    // dummy implementations of them here, even though they"re never used.
    public void paint(Graphics g, Shape allocation) {
    }
    public float getPreferredSpan(int axis) {
      return 0.0f;
    }
    public int viewToModel(float x, float y, Shape a, Position.Bias[] bias) {
      return 0;
    }
    public Shape modelToView(int pos, Shape a, Position.Bias b)
        throws BadLocationException {
      return a;
    }
  }
}



Print an Image to print directly

   
import java.io.FileInputStream;
import java.io.IOException;
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.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Copies;
public class PrintImage {
  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);
    if (pss.length == 0)
      throw new RuntimeException("No printer services available.");
    PrintService ps = pss[0];
    System.out.println("Printing to " + ps);
    DocPrintJob job = ps.createPrintJob();
    FileInputStream fin = new FileInputStream("YOurImageFileName.PNG");
    Doc doc = new SimpleDoc(fin, DocFlavor.INPUT_STREAM.GIF, null);
    job.print(doc, pras);
    fin.close();
  }
}



Print Dialog: change the default printer settings(default printer, number of copies, range of pages)

   
import java.awt.print.PageFormat;
import java.awt.print.PrinterJob;
public class Main {
  public static void main(String[] argv) throws Exception {
    PrinterJob pjob = PrinterJob.getPrinterJob();
    PageFormat pf = pjob.defaultPage();
    pjob.setPrintable(null, pf);
    if (pjob.printDialog()) {
      pjob.print();
    }
  }
}



PrintFile -- Print a file named on the command line

   
/*
 * Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002.
 * All rights reserved. Software written by Ian F. Darwin and others.
 * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
 * 
 * Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee
 * cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s,
 * pioneering role in inventing and promulgating (and standardizing) the Java 
 * language and environment is gratefully acknowledged.
 * 
 * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
 * inventing predecessor languages C and C++ is also gratefully acknowledged.
 */

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
/**
 * PrintFile -- Print a file named on the command line
 */
public class AnotherPrintFile extends Frame {
  /** The number of pages to print */
  protected static final int NPAGES = 3;
  /** The actual number of pages */
  protected int nPages;
  /** The PrintJob object */
  PrintJob pjob = null;  // refers to whole print job
  /** main program: instantiate and show. */
  public static void main(String[] av) {
    AnotherPrintFile p = new AnotherPrintFile();
    p.setVisible(true);
    if (av.length==0)
      p.print(new InputStreamReader(System.in));
    else
      for (int i=0; i<av.length; i++)
        p.print(av[i]);
    p.setVisible(false);
    p.dispose();
    System.exit(0);
  }
  /** Construct a PrintFile object */
  AnotherPrintFile() {
    setLayout(new FlowLayout());
    Button b;
    add(b = new Button("Cancel"));
    b.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        if (pjob != null)  // if quit while printing!
          pjob.end();
        System.exit(0);
      }
    });
    pack();
  }
  /** Print a file by name */
  public void print(String fn) {
    // open it, call the other guy 
    FileReader ifile = null;
    try {
      ifile = new FileReader(fn);
    } catch (FileNotFoundException fnf) {
      System.err.println("File not found!");
    }
    print(ifile);
  }
  /** Print a file by File */
  public void print(Reader ifile) {
    BufferedReader is = new BufferedReader(ifile);
    Graphics g = null;  // refers to current page
    System.out.println("Doing print");
    pjob = getToolkit().getPrintJob(this,
      "Printing Test", (Properties)null);
    if (pjob == null)          // User cancelled??
      return;
    Dimension pDim = pjob.getPageDimension();
    int pRes = pjob.getPageResolution();
    System.out.println("Page size " + pDim + "; Res " + pRes);
    g = pjob.getGraphics();
    g.setColor(Color.black);
    g.setFont(new Font("SansSerif", Font.PLAIN, 12));
    int y = 100;
    String line;
    try {
      while ((line = is.readLine()) != null) {
        g.drawString(line, 10, y+=18);
      }
    } catch (IOException e) {
      System.err.println(e);
    }
    // g.drawString("Page " + pgNum, 300, 300);
    g.dispose(); // flush page
    pjob.end();  // total end of print job.
    pjob = null;  // avoid redundant calls to pjob.end()
  }
}



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 the Combined-Java 1.2-and-1.4 Way

   
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ruponent;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.CubicCurve2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
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.attribute.DocAttributeSet;
import javax.print.attribute.HashDocAttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class PrintingOneTwoFour {
  static class MyComponent extends JPanel implements Printable {
    public void paint(Graphics g) {
      Graphics2D g2d = (Graphics2D) g;
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
          RenderingHints.VALUE_ANTIALIAS_ON);
      g2d.setPaint(Color.BLUE);
      g2d.setStroke(new BasicStroke(3));
      CubicCurve2D cubic = new CubicCurve2D.Float(10, 80, 60, 30, 110, 130, 160, 80);
      g2d.draw(cubic);
    }
    public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
      if (pageIndex == 0) {
        paint(g);
        return Printable.PAGE_EXISTS;
      } else {
        return Printable.NO_SUCH_PAGE;
      }
    }
  }
  public static void main(String args[]) throws Exception {
    final JFrame frame = new JFrame();
    Container contentPane = frame.getContentPane();
    final Component printIt = new MyComponent();
    contentPane.add(printIt, BorderLayout.CENTER);
    JButton button = new JButton("Print");
    contentPane.add(button, BorderLayout.SOUTH);
    ActionListener listener = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
        PrintService printService = PrintServiceLookup
            .lookupDefaultPrintService();
        DocPrintJob job = printService.createPrintJob();
        PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
        DocAttributeSet das = new HashDocAttributeSet();
        Doc doc = new SimpleDoc(printIt, flavor, das);
        try {
          job.print(doc, pras);
        } catch (PrintException pe) {
          pe.printStackTrace();
        }
      }
    };
    button.addActionListener(listener);
    frame.setSize(350, 350);
    frame.show();
  }
}



Printing the Java 1.1 Way

   
import java.awt.BorderLayout;
import java.awt.ruponent;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Polygon;
import java.awt.PrintJob;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class PrintingOneOne {
  static class MyComponent extends JPanel {
    Random random = new Random();
    public void paint(Graphics g) {
      Polygon convex, concave, selfintersecting;
      convex = new Polygon();
      convex.addPoint(20, 20);
      concave = new Polygon();
      concave.addPoint(100 + 20, 20);
      concave.addPoint(100 + 60, 24);
      selfintersecting = new Polygon();
      for (int i = 0; i < 8; i++) {
        selfintersecting.addPoint(200 + random.nextInt(80), 20 + random
            .nextInt(80));
      }
      g.fillPolygon(convex);
      g.drawPolygon(concave);
      g.fillPolygon(selfintersecting);
    }
  }
  public static void main(String args[]) {
    final JFrame frame = new JFrame("Printing 1.1");
    Container contentPane = frame.getContentPane();
    final Component printIt = new MyComponent();
    contentPane.add(printIt, BorderLayout.CENTER);
    JButton button = new JButton("Print");
    contentPane.add(button, BorderLayout.SOUTH);
    ActionListener listener = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        Toolkit def = Toolkit.getDefaultToolkit();
        PrintJob job = def.getPrintJob(frame, "Print Job", null);
        if (job != null) {
          Graphics pg = job.getGraphics();
          printIt.print(pg);
          pg.dispose();
          job.end();
        }
      }
    };
    button.addActionListener(listener);
    frame.setSize(300, 200);
    frame.show();
  }
}



Printing the Java 1.4 Way

   
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.DocAttributeSet;
import javax.print.attribute.HashDocAttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.event.PrintJobAdapter;
import javax.print.event.PrintJobEvent;
import javax.print.event.PrintJobListener;
public class PrintingOneFour {
  public static void main(String args[]) throws Exception {
    String filename = args[0];
    DocFlavor flavor = DocFlavor.INPUT_STREAM.GIF;
    PrintService printService = PrintServiceLookup
        .lookupDefaultPrintService();
    DocPrintJob job = printService.createPrintJob();
    PrintJobListener listener = new PrintJobAdapter() {
      public void printDataTransferCompleted(PrintJobEvent e) {
        System.out.println("Good-bye");
        System.exit(0);
      }
    };
    job.addPrintJobListener(listener);
    PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
    FileInputStream fis = new FileInputStream(filename);
    DocAttributeSet das = new HashDocAttributeSet();
    Doc doc = new SimpleDoc(fis, flavor, das);
    job.print(doc, pras);
    Thread.sleep(10000);
  }
}



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 in Java 2: PrinterJob

   
/**
 * Class: Example2
 * <p>
 * 
 * Print in Java series for the JavaWorld magazine.
 * 
 * @author Jean-Pierre Dube <jpdube@videotron.ca>
 * @version 1.0
 * @since 1.0
 */
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterJob;
public class JavaWorldPrintExample2 {
  public static void main(String[] args) {
    JavaWorldPrintExample2 example2 = new JavaWorldPrintExample2();
    System.exit(0);
  }
  //--- Private instances declarations
  private final static int POINTS_PER_INCH = 72;
  /**
   * Constructor: Example2
   * <p>
   *  
   */
  public JavaWorldPrintExample2() {
    //--- Create a new PrinterJob object
    PrinterJob printJob = PrinterJob.getPrinterJob();
    //--- Create a new book to add pages to
    Book book = new Book();
    //--- Add the cover page using the default page format for this print
    // job
    book.append(new IntroPage(), printJob.defaultPage());
    //--- Add the document page using a landscape page format
    PageFormat documentPageFormat = new PageFormat();
    documentPageFormat.setOrientation(PageFormat.LANDSCAPE);
    book.append(new Document(), documentPageFormat);
    //--- Tell the printJob to use the book as the pageable object
    printJob.setPageable(book);
    //--- Show the print dialog box. If the user click the
    //--- print button we then proceed to print else we cancel
    //--- the process.
    if (printJob.printDialog()) {
      try {
        printJob.print();
      } catch (Exception PrintException) {
        PrintException.printStackTrace();
      }
    }
  }
  /**
   * Class: IntroPage
   * <p>
   * 
   * This class defines the painter for the cover page by implementing the
   * Printable interface.
   * <p>
   * 
   * @author Jean-Pierre Dube <jpdube@videotron.ca>
   * @version 1.0
   * @since 1.0
   * @see Printable
   */
  private class IntroPage implements Printable {
    /**
     * Method: print
     * <p>
     * 
     * @param g
     *            a value of type Graphics
     * @param pageFormat
     *            a value of type PageFormat
     * @param page
     *            a value of type int
     * @return a value of type int
     */
    public int print(Graphics g, PageFormat pageFormat, int page) {
      //--- Create the Graphics2D object
      Graphics2D g2d = (Graphics2D) g;
      //--- Translate the origin to 0,0 for the top left corner
      g2d.translate(pageFormat.getImageableX(), pageFormat
          .getImageableY());
      //--- Set the default drawing color to black
      g2d.setPaint(Color.black);
      //--- Draw a border arround the page
      Rectangle2D.Double border = new Rectangle2D.Double(0, 0, pageFormat
          .getImageableWidth(), pageFormat.getImageableHeight());
      g2d.draw(border);
      //--- Print the title
      String titleText = "Printing in Java Part 2";
      Font titleFont = new Font("helvetica", Font.BOLD, 36);
      g2d.setFont(titleFont);
      //--- Compute the horizontal center of the page
      FontMetrics fontMetrics = g2d.getFontMetrics();
      double titleX = (pageFormat.getImageableWidth() / 2)
          - (fontMetrics.stringWidth(titleText) / 2);
      double titleY = 3 * POINTS_PER_INCH;
      g2d.drawString(titleText, (int) titleX, (int) titleY);
      return (PAGE_EXISTS);
    }
  }
  /**
   * Class: Document
   * <p>
   * 
   * This class is the painter for the document content.
   * <p>
   * 
   * 
   * @author Jean-Pierre Dube <jpdube@videotron.ca>
   * @version 1.0
   * @since 1.0
   * @see Printable
   */
  private class Document implements Printable {
    /**
     * Method: print
     * <p>
     * 
     * @param g
     *            a value of type Graphics
     * @param pageFormat
     *            a value of type PageFormat
     * @param page
     *            a value of type int
     * @return a value of type int
     */
    public int print(Graphics g, PageFormat pageFormat, int page) {
      //--- Create the Graphics2D object
      Graphics2D g2d = (Graphics2D) g;
      //--- Translate the origin to 0,0 for the top left corner
      g2d.translate(pageFormat.getImageableX(), pageFormat
          .getImageableY());
      //--- Set the drawing color to black
      g2d.setPaint(Color.black);
      //--- Draw a border arround the page using a 12 point border
      g2d.setStroke(new BasicStroke(12));
      Rectangle2D.Double border = new Rectangle2D.Double(0, 0, pageFormat
          .getImageableWidth(), pageFormat.getImageableHeight());
      g2d.draw(border);
      //--- Print the text one inch from the top and laft margins
      g2d.drawString("This the content page", POINTS_PER_INCH,
          POINTS_PER_INCH);
      //--- Validate the page
      return (PAGE_EXISTS);
    }
  }
} // Example2



Print in Java 5

   
/**
 * Class: Example5
 * <p>
 * 
 * Example of using the TextLayout class to format a text paragraph. with full
 * justification.
 * <p>
 * 
 * @author Jean-Pierre Dube <jpdube@videotron.ca>
 * @version 1.0
 * @since 1.0
 */
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterJob;
import java.text.AttributedString;
import java.util.Vector;
public class JavaWorldPrintExample5 {
  public static void main(String[] args) {
    JavaWorldPrintExample5 example = new JavaWorldPrintExample5();
    System.exit(0);
  }
  //--- Private instances declarations
  private final static int POINTS_PER_INCH = 72;
  /**
   * Constructor: Example5
   * <p>
   *  
   */
  public JavaWorldPrintExample5() {
    //--- Create a new PrinterJob object
    PrinterJob printJob = PrinterJob.getPrinterJob();
    //--- Create a new book to add pages to
    Book book = new Book();
    //--- Add the cover page using the default page format for this print
    // job
    book.append(new IntroPage(), printJob.defaultPage());
    //--- Add the document page using a landscape page format
    PageFormat documentPageFormat = new PageFormat();
    documentPageFormat.setOrientation(PageFormat.LANDSCAPE);
    book.append(new Document(), documentPageFormat);
    //--- Tell the printJob to use the book as the pageable object
    printJob.setPageable(book);
    //--- Show the print dialog box. If the user click the
    //--- print button we then proceed to print else we cancel
    //--- the process.
    if (printJob.printDialog()) {
      try {
        printJob.print();
      } catch (Exception PrintException) {
        PrintException.printStackTrace();
      }
    }
  }
  /**
   * Class: IntroPage
   * <p>
   * 
   * This class defines the painter for the cover page by implementing the
   * Printable interface.
   * <p>
   * 
   * @author Jean-Pierre Dube <jpdube@videotron.ca>
   * @version 1.0
   * @since 1.0
   * @see Printable
   */
  private class IntroPage implements Printable {
    /**
     * Method: print
     * <p>
     * 
     * @param g
     *            a value of type Graphics
     * @param pageFormat
     *            a value of type PageFormat
     * @param page
     *            a value of type int
     * @return a value of type int
     */
    public int print(Graphics g, PageFormat pageFormat, int page) {
      //--- Create the Graphics2D object
      Graphics2D g2d = (Graphics2D) g;
      //--- Translate the origin to 0,0 for the top left corner
      g2d.translate(pageFormat.getImageableX(), pageFormat
          .getImageableY());
      //--- Set the default drawing color to black
      g2d.setPaint(Color.black);
      //--- Draw a border arround the page
      Rectangle2D.Double border = new Rectangle2D.Double(0, 0, pageFormat
          .getImageableWidth(), pageFormat.getImageableHeight());
      g2d.draw(border);
      //--- Print the title
      String titleText = "Printing in Java Part 2, Example 5, Using full justification";
      Font titleFont = new Font("helvetica", Font.BOLD, 18);
      g2d.setFont(titleFont);
      //--- Compute the horizontal center of the page
      FontMetrics fontMetrics = g2d.getFontMetrics();
      double titleX = (pageFormat.getImageableWidth() / 2)
          - (fontMetrics.stringWidth(titleText) / 2);
      double titleY = 3 * POINTS_PER_INCH;
      g2d.drawString(titleText, (int) titleX, (int) titleY);
      return (PAGE_EXISTS);
    }
  }
  /**
   * Class: Document
   * <p>
   * 
   * This class is the painter for the document content. The print method will
   * render a text paragraph fully justified.
   * <p>
   * 
   * 
   * @author Jean-Pierre Dube <jpdube@videotron.ca>
   * @version 1.0
   * @since 1.0
   * @see Printable
   */
  private class Document implements Printable {
    /**
     * Method: print
     * <p>
     * 
     * @param g
     *            a value of type Graphics
     * @param pageFormat
     *            a value of type PageFormat
     * @param page
     *            a value of type int
     * @return a value of type int
     */
    public int print(Graphics g, PageFormat pageFormat, int page) {
      //--- Create the Graphics2D object
      Graphics2D g2d = (Graphics2D) g;
      //--- Translate the origin to 0,0 for the top left corner
      g2d.translate(pageFormat.getImageableX(), pageFormat
          .getImageableY());
      //--- Set the drawing color to black
      g2d.setPaint(Color.black);
      //--- Draw a border arround the page using a 12 point border
      g2d.setStroke(new BasicStroke(4));
      Rectangle2D.Double border = new Rectangle2D.Double(0, 0, pageFormat
          .getImageableWidth(), pageFormat.getImageableHeight());
      g2d.draw(border);
      //--- Create a string and assign the text
      String text = new String();
      text += "Manipulating raw fonts would be too complicated to render paragraphs of ";
      text += "text. Trying to write an algorithm to fully justify text using ";
      text += "proportional fonts is not trivial. Adding support for international ";
      text += "characters adds to the complexity. That"s why we will use the ";
      text += "<code>TextLayout</code> and the <code>LineBreakMeasurer<code> class to ";
      text += "render text. The <code>TextLayout<code> class offers a lot of ";
      text += "functionality to render high quality text. This class is capable of ";
      text += "rendering bidirectional text such as Japanese text where the alignment ";
      text += "is from right to left instead of the North American style which is left ";
      text += "to right. The <code>TextLayout<code> class offers some additional ";
      text += "functionalities that we will not use in the course of this ";
      text += "series. Features such as text input, caret positionning and hit ";
      text += "testing will not be of much use when printing documents, but it"s good ";
      text += "to know that this functionality exists. ";
      text += "The <code>TextLayout</code> class will be used to layout ";
      text += "paragraphs. The <code>TextLayout</code> class does not work alone. To ";
      text += "layout text within a specified width it needs the help of the ";
      text += "<code>LineBreakMeasurer</code> class. This class will wrap a string of ";
      text += "text to fit a predefined width. Since it"s a multi-lingual class, it ";
      text += "knows exactly where to break a line of text according to the rules ";
      text += "of the language.  Then again the <code>LineBreakMeasurer</code> does ";
      text += "not work alone. It needs information from the ";
      text += "<code>FontRenderContext</code> class. This class" main function is to ";
      text += "return accurate font metrics. To measure text effectively, this class ";
      text += "needs to know the rendering hints for the targeted device and the font ";
      text += "type being used. ";
      //--- Create a point object to set the top left corner of the
      // TextLayout object
      Point2D.Double pen = new Point2D.Double(0.25 * POINTS_PER_INCH,
          0.25 * POINTS_PER_INCH);
      //--- Set the width of the TextLayout box
      double width = 8 * POINTS_PER_INCH;
      //--- Create an attributed string from the text string. We are
      // creating an
      //--- attributed string because the LineBreakMeasurer needs an
      // Iterator as
      //--- parameter.
      AttributedString paragraphText = new AttributedString(text);
      //--- Set the font for this text
      paragraphText.addAttribute(TextAttribute.FONT, new Font("serif",
          Font.PLAIN, 12));
      //--- Create a LineBreakMeasurer to wrap the text for the
      // TextLayout object
      //--- Note the second parameter, the FontRendereContext. I have set
      // the second
      //--- parameter antiAlised to true and the third parameter
      // useFractionalMetrics
      //--- to true to get the best possible output
      LineBreakMeasurer lineBreaker = new LineBreakMeasurer(paragraphText
          .getIterator(), new FontRenderContext(null, true, true));
      //--- Create the TextLayouts object
      TextLayout layout;
      TextLayout justifyLayout;
      //--- Create a Vector to temporaly store each line of text
      Vector lines = new Vector();
      //--- Get the output of the LineBreakMeasurer and store it in a
      // Vector
      while ((layout = lineBreaker.nextLayout((float) width)) != null) {
        lines.add(layout);
      }
      //--- Scan each line of the paragraph and justify it except for the
      // last line
      for (int i = 0; i < lines.size(); i++) {
        //--- Get the line from the vector
        layout = (TextLayout) lines.get(i);
        //--- Check for the last line. When found print it
        //--- with justification off
        if (i != lines.size() - 1)
          justifyLayout = layout.getJustifiedLayout((float) width);
        else
          justifyLayout = layout;
        //--- Align the Y pen to the ascend of the font, remember that
        //--- the ascend is origin (0, 0) of a font. Refer to figure 1
        pen.y += justifyLayout.getAscent();
        //--- Draw the line of text
        justifyLayout.draw(g2d, (float) pen.x, (float) pen.y);
        //--- Move the pen to the next position adding the descent and
        //--- the leading of the font
        pen.y += justifyLayout.getDescent()
            + justifyLayout.getLeading();
      }
      //--- Validate the page
      return (PAGE_EXISTS);
    }
  }
} // Example5



Print in Java 6

   
/**
 * Class: Example6
 * <p>
 * 
 * Example on how to print an image.
 * <p>
 * 
 * @author Jean-Pierre Dube <jpdube@videotron.ca>
 * @version 1.0
 * @since 1.0
 */
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.ruponent;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.geom.Rectangle2D;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterJob;
import java.net.MalformedURLException;
import java.net.URL;
public class JavaWorldPrintExample6 {
  public static void main(String[] args) {
    JavaWorldPrintExample6 example = new JavaWorldPrintExample6();
    System.exit(0);
  }
  //--- Private instances declarations
  private final static int POINTS_PER_INCH = 72;
  /**
   * Constructor: Example6
   * <p>
   *  
   */
  public JavaWorldPrintExample6() {
    //--- Create a new PrinterJob object
    PrinterJob printJob = PrinterJob.getPrinterJob();
    //--- Create a new book to add pages to
    Book book = new Book();
    //--- Add the cover page using the default page format for this print
    // job
    book.append(new IntroPage(), printJob.defaultPage());
    //--- Add the document page using a landscape page format
    PageFormat documentPageFormat = new PageFormat();
    documentPageFormat.setOrientation(PageFormat.LANDSCAPE);
    book.append(new Document(), documentPageFormat);
    //--- Tell the printJob to use the book as the pageable object
    printJob.setPageable(book);
    //--- Show the print dialog box. If the user click the
    //--- print button we then proceed to print else we cancel
    //--- the process.
    if (printJob.printDialog()) {
      try {
        printJob.print();
      } catch (Exception PrintException) {
        PrintException.printStackTrace();
      }
    }
  }
  /**
   * Class: IntroPage
   * <p>
   * 
   * This class defines the painter for the cover page by implementing the
   * Printable interface.
   * <p>
   * 
   * @author Jean-Pierre Dube <jpdube@videotron.ca>
   * @version 1.0
   * @since 1.0
   * @see Printable
   */
  private class IntroPage implements Printable {
    /**
     * Method: print
     * <p>
     * 
     * @param g
     *            a value of type Graphics
     * @param pageFormat
     *            a value of type PageFormat
     * @param page
     *            a value of type int
     * @return a value of type int
     */
    public int print(Graphics g, PageFormat pageFormat, int page) {
      //--- Create the Graphics2D object
      Graphics2D g2d = (Graphics2D) g;
      //--- Translate the origin to 0,0 for the top left corner
      g2d.translate(pageFormat.getImageableX(), pageFormat
          .getImageableY());
      //--- Set the default drawing color to black
      g2d.setPaint(Color.black);
      //--- Draw a border arround the page
      Rectangle2D.Double border = new Rectangle2D.Double(0, 0, pageFormat
          .getImageableWidth(), pageFormat.getImageableHeight());
      g2d.draw(border);
      //--- Print the title
      String titleText = "Printing in Java Part 2, Example 6, Printing an image";
      Font titleFont = new Font("helvetica", Font.BOLD, 18);
      g2d.setFont(titleFont);
      //--- Compute the horizontal center of the page
      FontMetrics fontMetrics = g2d.getFontMetrics();
      double titleX = (pageFormat.getImageableWidth() / 2)
          - (fontMetrics.stringWidth(titleText) / 2);
      double titleY = 3 * POINTS_PER_INCH;
      g2d.drawString(titleText, (int) titleX, (int) titleY);
      return (PAGE_EXISTS);
    }
  }
  /**
   * Class: Document
   * <p>
   * 
   * This class is the painter for the document content. In this example, it
   * will print an image of the Nasa Space Station with a border arround it.
   * <p>
   * 
   * 
   * @author Jean-Pierre Dube <jpdube@videotron.ca>
   * @version 1.0
   * @since 1.0
   * @see Printable
   */
  private class Document extends Component implements Printable {
    /**
     * Method: print
     * <p>
     * 
     * @param g
     *            a value of type Graphics
     * @param pageFormat
     *            a value of type PageFormat
     * @param page
     *            a value of type int
     * @return a value of type int
     */
    public int print(Graphics g, PageFormat pageFormat, int page) {
      //--- Create the Graphics2D object
      Graphics2D g2d = (Graphics2D) g;
      //--- Translate the origin to 0,0 for the top left corner
      g2d.translate(pageFormat.getImageableX(), pageFormat
          .getImageableY());
      //--- Set the drawing color to black
      g2d.setPaint(Color.black);
      //--- Draw a border arround the page using a 12 point border
      g2d.setStroke(new BasicStroke(4));
      Rectangle2D.Double border = new Rectangle2D.Double(0, 0, pageFormat
          .getImageableWidth(), pageFormat.getImageableHeight());
      g2d.draw(border);
      //--- Create a media tracker and a URL object
      MediaTracker mt = new MediaTracker(this);
      URL imageURL = null;
      //--- Set the URL to the image that we want to load.
      //--- NOTE: Change the path to reflect your location of the image
      //--- NOTE: Only the following image type are supported JPEG, GIF
      // and PNG.
      try {
        imageURL = new URL(
            "file:///c:/softdev/java/articles/javaworld/printing/part_2/ss2.jpg");
      } catch (MalformedURLException me) {
        me.printStackTrace();
      }
      //--- Load the image and wait for it to load
      Image image = Toolkit.getDefaultToolkit().getImage(imageURL);
      mt.addImage(image, 0);
      try {
        mt.waitForID(0);
      } catch (InterruptedException e) {
      }
      //--- Render the image on the sheet
      g2d.drawImage(image, (int) (0.25 * POINTS_PER_INCH),
          (int) (0.25 * POINTS_PER_INCH),
          (int) (8.5 * POINTS_PER_INCH), (int) (6 * POINTS_PER_INCH),
          this);
      //--- Validate the page
      return (PAGE_EXISTS);
    }
  }
} // Example6



Print in Java: Multi page

   
/**
 * Class: Example4
 * <p>
 * 
 * Example of using the TextLayout class to format a text paragraph.
 * <p>
 * 
 * @author Jean-Pierre Dube <jpdube@videotron.ca>
 * @version 1.0
 * @since 1.0
 */
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterJob;
import java.text.AttributedString;
public class JavaWorldPrintExample4 {
  public static void main(String[] args) {
    JavaWorldPrintExample4 example = new JavaWorldPrintExample4();
    System.exit(0);
  }
  //--- Private instances declarations
  private final static int POINTS_PER_INCH = 72;
  /**
   * Constructor: Example4
   * <p>
   *  
   */
  public JavaWorldPrintExample4() {
    //--- Create a new PrinterJob object
    PrinterJob printJob = PrinterJob.getPrinterJob();
    //--- Create a new book to add pages to
    Book book = new Book();
    //--- Add the cover page using the default page format for this print
    // job
    book.append(new IntroPage(), printJob.defaultPage());
    //--- Add the document page using a landscape page format
    PageFormat documentPageFormat = new PageFormat();
    documentPageFormat.setOrientation(PageFormat.LANDSCAPE);
    book.append(new Document(), documentPageFormat);
    //--- Tell the printJob to use the book as the pageable object
    printJob.setPageable(book);
    //--- Show the print dialog box. If the user click the
    //--- print button we then proceed to print else we cancel
    //--- the process.
    if (printJob.printDialog()) {
      try {
        printJob.print();
      } catch (Exception PrintException) {
        PrintException.printStackTrace();
      }
    }
  }
  /**
   * Class: IntroPage
   * <p>
   * 
   * This class defines the painter for the cover page by implementing the
   * Printable interface.
   * <p>
   * 
   * @author Jean-Pierre Dube <jpdube@videotron.ca>
   * @version 1.0
   * @since 1.0
   * @see Printable
   */
  private class IntroPage implements Printable {
    /**
     * Method: print
     * <p>
     * 
     * @param g
     *            a value of type Graphics
     * @param pageFormat
     *            a value of type PageFormat
     * @param page
     *            a value of type int
     * @return a value of type int
     */
    public int print(Graphics g, PageFormat pageFormat, int page) {
      //--- Create the Graphics2D object
      Graphics2D g2d = (Graphics2D) g;
      //--- Translate the origin to 0,0 for the top left corner
      g2d.translate(pageFormat.getImageableX(), pageFormat
          .getImageableY());
      //--- Set the default drawing color to black
      g2d.setPaint(Color.black);
      //--- Draw a border arround the page
      Rectangle2D.Double border = new Rectangle2D.Double(0, 0, pageFormat
          .getImageableWidth(), pageFormat.getImageableHeight());
      g2d.draw(border);
      //--- Print the title
      String titleText = "Printing in Java Part 2, Example 4";
      Font titleFont = new Font("helvetica", Font.BOLD, 18);
      g2d.setFont(titleFont);
      //--- Compute the horizontal center of the page
      FontMetrics fontMetrics = g2d.getFontMetrics();
      double titleX = (pageFormat.getImageableWidth() / 2)
          - (fontMetrics.stringWidth(titleText) / 2);
      double titleY = 3 * POINTS_PER_INCH;
      g2d.drawString(titleText, (int) titleX, (int) titleY);
      return (PAGE_EXISTS);
    }
  }
  /**
   * Class: Document
   * <p>
   * 
   * This class is the painter for the document content.
   * <p>
   * 
   * 
   * @author Jean-Pierre Dube <jpdube@videotron.ca>
   * @version 1.0
   * @since 1.0
   * @see Printable
   */
  private class Document implements Printable {
    /**
     * Method: print
     * <p>
     * 
     * @param g
     *            a value of type Graphics
     * @param pageFormat
     *            a value of type PageFormat
     * @param page
     *            a value of type int
     * @return a value of type int
     */
    public int print(Graphics g, PageFormat pageFormat, int page) {
      //--- Create the Graphics2D object
      Graphics2D g2d = (Graphics2D) g;
      //--- Translate the origin to 0,0 for the top left corner
      g2d.translate(pageFormat.getImageableX(), pageFormat
          .getImageableY());
      //--- Set the drawing color to black
      g2d.setPaint(Color.black);
      //--- Draw a border arround the page using a 12 point border
      g2d.setStroke(new BasicStroke(4));
      Rectangle2D.Double border = new Rectangle2D.Double(0, 0, pageFormat
          .getImageableWidth(), pageFormat.getImageableHeight());
      g2d.draw(border);
      //--- Create a string and assign the text
      String text = new String();
      text += "Manipulating raw fonts would be too complicated to render paragraphs of ";
      text += "text. Trying to write an algorithm to fully justify text using ";
      text += "proportional fonts is not trivial. Adding support for international ";
      text += "characters adds to the complexity. That"s why we will use the ";
      text += "<code>TextLayout</code> and the <code>LineBreakMeasurer<code> class to ";
      text += "render text. The <code>TextLayout<code> class offers a lot of ";
      text += "functionality to render high quality text. This class is capable of ";
      text += "rendering bidirectional text such as Japanese text where the alignment ";
      text += "is from right to left instead of the North American style which is left ";
      text += "to right. The <code>TextLayout<code> class offers some additional ";
      text += "functionalities that we will not use in the course of this ";
      text += "series. Features such as text input, caret positionning and hit ";
      text += "testing will not be of much use when printing documents, but it"s good ";
      text += "to know that this functionality exists. ";
      text += "The <code>TextLayout</code> class will be used to layout ";
      text += "paragraphs. The <code>TextLayout</code> class does not work alone. To ";
      text += "layout text within a specified width it needs the help of the ";
      text += "<code>LineBreakMeasurer</code> class. This class will wrap a string of ";
      text += "text to fit a predefined width. Since it"s a multi-lingual class, it ";
      text += "knows exactly where to break a line of text according to the rules ";
      text += "of the language.  Then again the <code>LineBreakMeasurer</code> does ";
      text += "not work alone. It needs information from the ";
      text += "<code>FontRenderContext</code> class. This class" main function is to ";
      text += "return accurate font metrics. To measure text effectively, this class ";
      text += "needs to know the rendering hints for the targeted device and the font ";
      text += "type being used. ";
      //--- Create a point object to set the top left corner of the
      // TextLayout object
      Point2D.Double pen = new Point2D.Double(0.25 * POINTS_PER_INCH,
          0.25 * POINTS_PER_INCH);
      //--- Set the width of the TextLayout box
      double width = 7.5 * POINTS_PER_INCH;
      //--- Create an attributed string from the text string. We are
      // creating an
      //--- attributed string because the LineBreakMeasurer needs an
      // Iterator as
      //--- parameter.
      AttributedString paragraphText = new AttributedString(text);
      //--- Set the font for this text
      paragraphText.addAttribute(TextAttribute.FONT, new Font("serif",
          Font.PLAIN, 12));
      //--- Create a LineBreakMeasurer to wrap the text for the
      // TextLayout object
      //--- Note the second parameter, the FontRendereContext. I have set
      // the second
      //--- parameter antiAlised to true and the third parameter
      // useFractionalMetrics
      //--- to true to get the best possible output
      LineBreakMeasurer lineBreaker = new LineBreakMeasurer(paragraphText
          .getIterator(), new FontRenderContext(null, true, true));
      //--- Create the TextLayout object
      TextLayout layout;
      //--- LineBreakMeasurer will wrap each line to correct length and
      //--- return it as a TextLayout object
      while ((layout = lineBreaker.nextLayout((float) width)) != null) {
        //--- Align the Y pen to the ascend of the font, remember that
        //--- the ascend is origin (0, 0) of a font. Refer to figure 1
        pen.y += layout.getAscent();
        //--- Draw the line of text
        layout.draw(g2d, (float) pen.x, (float) pen.y);
        //--- Move the pen to the next position adding the descent and
        //--- the leading of the font
        pen.y += layout.getDescent() + layout.getLeading();
      }
      //--- Validate the page
      return (PAGE_EXISTS);
    }
  }
} // Example4



Print in Java: page format and document

   

/**
 * Class: Example3
 * <p>
 * 
 * @author Jean-Pierre Dube <jpdube@videotron.ca>
 * @version 1.0
 * @since 1.0
 */
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterJob;
public class JavaWorldPrintExample3 {
  public static void main(String[] args) {
    JavaWorldPrintExample3 example3 = new JavaWorldPrintExample3();
    System.exit(0);
  }
  //--- Private instances declarations
  private final static int POINTS_PER_INCH = 72;
  /**
   * Constructor: Example3
   * <p>
   *  
   */
  public JavaWorldPrintExample3() {
    //--- Create a new PrinterJob object
    PrinterJob printJob = PrinterJob.getPrinterJob();
    //--- Create a new book to add pages to
    Book book = new Book();
    //--- Add the cover page using the default page format for this print
    // job
    book.append(new IntroPage(), printJob.defaultPage());
    //--- Add the document page using a landscape page format
    PageFormat documentPageFormat = new PageFormat();
    documentPageFormat.setOrientation(PageFormat.LANDSCAPE);
    book.append(new Document(), documentPageFormat);
    //--- Add a third page using the same painter
    book.append(new Document(), documentPageFormat);
    //--- Tell the printJob to use the book as the pageable object
    printJob.setPageable(book);
    //--- Show the print dialog box. If the user click the
    //--- print button we then proceed to print else we cancel
    //--- the process.
    if (printJob.printDialog()) {
      try {
        printJob.print();
      } catch (Exception PrintException) {
        PrintException.printStackTrace();
      }
    }
  }
  /**
   * Class: IntroPage
   * <p>
   * 
   * This class defines the painter for the cover page by implementing the
   * Printable interface.
   * <p>
   * 
   * @author Jean-Pierre Dube <jpdube@videotron.ca>
   * @version 1.0
   * @since 1.0
   * @see Printable
   */
  private class IntroPage implements Printable {
    /**
     * Method: print
     * <p>
     * 
     * @param g
     *            a value of type Graphics
     * @param pageFormat
     *            a value of type PageFormat
     * @param page
     *            a value of type int
     * @return a value of type int
     */
    public int print(Graphics g, PageFormat pageFormat, int page) {
      //--- Create the Graphics2D object
      Graphics2D g2d = (Graphics2D) g;
      //--- Translate the origin to 0,0 for the top left corner
      g2d.translate(pageFormat.getImageableX(), pageFormat
          .getImageableY());
      //--- Set the default drawing color to black
      g2d.setPaint(Color.black);
      //--- Draw a border arround the page
      Rectangle2D.Double border = new Rectangle2D.Double(0, 0, pageFormat
          .getImageableWidth(), pageFormat.getImageableHeight());
      g2d.draw(border);
      //--- Print the title
      String titleText = "Printing in Java Part 2";
      Font titleFont = new Font("helvetica", Font.BOLD, 36);
      g2d.setFont(titleFont);
      //--- Compute the horizontal center of the page
      FontMetrics fontMetrics = g2d.getFontMetrics();
      double titleX = (pageFormat.getImageableWidth() / 2)
          - (fontMetrics.stringWidth(titleText) / 2);
      double titleY = 3 * POINTS_PER_INCH;
      g2d.drawString(titleText, (int) titleX, (int) titleY);
      return (PAGE_EXISTS);
    }
  }
  /**
   * Class: Document
   * <p>
   * 
   * This class is the painter for the document content.
   * <p>
   * 
   * 
   * @author Jean-Pierre Dube <jpdube@videotron.ca>
   * @version 1.0
   * @since 1.0
   * @see Printable
   */
  private class Document implements Printable {
    /**
     * Method: print
     * <p>
     * 
     * @param g
     *            a value of type Graphics
     * @param pageFormat
     *            a value of type PageFormat
     * @param page
     *            a value of type int
     * @return a value of type int
     */
    public int print(Graphics g, PageFormat pageFormat, int page) {
      //--- Create the Graphics2D object
      Graphics2D g2d = (Graphics2D) g;
      //--- Translate the origin to 0,0 for the top left corner
      g2d.translate(pageFormat.getImageableX(), pageFormat
          .getImageableY());
      //--- Set the drawing color to black
      g2d.setPaint(Color.black);
      //--- Draw a border arround the page using a 12 point border
      g2d.setStroke(new BasicStroke(12));
      Rectangle2D.Double border = new Rectangle2D.Double(0, 0, pageFormat
          .getImageableWidth(), pageFormat.getImageableHeight());
      g2d.draw(border);
      //--- Print page 1
      if (page == 1) {
        //--- Print the text one inch from the top and laft margins
        g2d.drawString("This the content page of page: " + page,
            POINTS_PER_INCH, POINTS_PER_INCH);
        return (PAGE_EXISTS);
      }
      //--- Print page 2
      else if (page == 2) {
        //--- Print the text one inch from the top and laft margins
        g2d.drawString("This the content of the second page: " + page,
            POINTS_PER_INCH, POINTS_PER_INCH);
        return (PAGE_EXISTS);
      }
      //--- Validate the page
      return (NO_SUCH_PAGE);
    }
  }
} // Example3



PrintPanel is the base for an open-ended series of classes

   
/*
 * Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002.
 * All rights reserved. Software written by Ian F. Darwin and others.
 * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
 * 
 * Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee
 * cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s,
 * pioneering role in inventing and promulgating (and standardizing) the Java 
 * language and environment is gratefully acknowledged.
 * 
 * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
 * inventing predecessor languages C and C++ is also gratefully acknowledged.
 */
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.CardLayout;
import java.awt.Checkbox;
import java.awt.Choice;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Panel;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * PrintPanel is the base for an open-ended series of classes that implement
 * printing of one type. We provide two examples to start: First prints a phone
 * book, second prints labels, etc. To add more, for example a Mail List/Form
 * Letter Merge, define a class for it below and insert in the "add" loop in the
 * main constructor.
 */
abstract class PrintPanel extends Panel {
  /** Returns the string to use in a Choice to display this panel */
  public abstract String getChoice();
  /** Print the data in the format for this type of printout */
  public abstract void doPrint();
}
/**
 * PhonesPanel extends PrintPanel to provide the UI for printing a user"s phone
 * book.
 */
class PhonesPanel extends PrintPanel {
  PhonesPanel() {
    super();
    setBackground(Color.red);
    setLayout(new FlowLayout());
    add(new Label("Tab markers at edge of page?"));
    add(new Checkbox());
    add(new Label("Each letter starts page?"));
    add(new Checkbox());
  }
  public String getChoice() {
    return "Phone Book";
  }
  public void doPrint() {
    // code here to print Phone book
  }
}
/**
 * LabelsPanel extends PrintPanel to provide the UI for printing name and
 * address labels
 */
class LabelsPanel extends PrintPanel {
  LabelsPanel() {
    super();
    setBackground(Color.green);
    setLayout(new GridLayout(3, 2));
    add(new Label("Left Offset:"));
    add(new TextField(5));
    add(new Label("Rows:"));
    add(new TextField(5));
    add(new Label("Cols:"));
    add(new TextField(5));
  }
  public String getChoice() {
    return "Labels";
  }
  public void doPrint() {
    // code here to print Labels
  }
}
/**
 * CardLayDemo2 -- Prototype of a Print Dialog for JabaDex
 * 
 * @author Ian F. Darwin
 * @version 0.0, September, 1996
 */
public class CardLayDemo2 extends Frame {
  PrintPanel[] pps = new PrintPanel[2];
  private int runType = 0;
  private Choice runTypeChoice;
  private Panel tp, mainP, bp; // top, middle, bottom.
  CardLayout cardlay;
  private Button printButton, sampleButton, cancelButton;
  /** Construct a Print dialog. */
  CardLayDemo2(String title) {
    super(title);
    // Top panel (tp) has choices for labels/phonebook/etc.
    // and paper size.
    // Middle panel (mainP, managed by CardLayout) is details
    // for either Labels or Phonebook
    //  Shows either a PhonesPanel or a LabelsPanel or ...
    // Bottom panel (bp) has Print/Preview/Cancel buttons.
    tp = new Panel();
    tp.setLayout(new FlowLayout());
    mainP = new Panel();
    mainP.setLayout(cardlay = new CardLayout());
    tp.add(runTypeChoice = new Choice());
    runTypeChoice.addItemListener(new ItemListener() {
      public void itemStateChanged(ItemEvent e) {
        runType = runTypeChoice.getSelectedIndex();
        cardlay.show(mainP, pps[runType].getChoice());
      }
    });
    /* create one instance of each PrintPanel type. */
    pps[0] = new PhonesPanel();
    pps[1] = new LabelsPanel();
    /* Add each print type to the choice and to mainP */
    for (int i = 0; i < pps.length; i++) {
      runTypeChoice.add(pps[i].getChoice());
      mainP.add(pps[i].getChoice(), pps[i]);
    }
    cardlay.show(mainP, pps[runType].getChoice());
    // Bottom has a Panel with push buttons
    bp = new Panel();
    bp.setLayout(new FlowLayout());
    bp.add(printButton = new Button("Print"));
    printButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        doPrint(true);
        setVisible(false);
        System.exit(0);
      }
    });
    bp.add(sampleButton = new Button("Print Sample"));
    sampleButton.setEnabled(false);
    bp.add(cancelButton = new Button("Cancel"));
    cancelButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        System.out.println("Printing canceled");
        setVisible(false);
        System.exit(0);
      }
    });
    setLayout(new BorderLayout());
    add(tp, BorderLayout.NORTH);
    add(mainP, BorderLayout.CENTER);
    add(bp, BorderLayout.SOUTH);
    pack();
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        // If windowClosing() does setVisible and dispose,
        // then the close action completes
        setVisible(false);
        dispose();
        System.exit(0);
      }
    });
  }
  /** Print the current list. */
  protected void doPrint(boolean toRealDevice) {
    // open a PrintStream to the printer device to file on disk.
    // PrintStream pf = ...
    // call the appropriate doPrint()
    // pps[runType].doPrint(pf);
    System.err.println("Print completed");
  }
  public static void main(String[] args) {
    // Generate some data...
    // ...
    // pop up the print dialog to print it
    (new CardLayDemo2("Print Tester")).setVisible(true);
  }
}



Print Swing components

   
import java.awt.Color;
import java.awt.ruponent;
import java.awt.Dimension;
import java.awt.Event;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.font.FontRenderContext;
import java.awt.font.LineMetrics;
import java.awt.geom.Rectangle2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.KeyStroke;
public class SwingPrinter extends JFrame {
  public static void main(String[] args) {
    new SwingPrinter();
  }
  private PageFormat mPageFormat;
  public SwingPrinter() {
    super("SwingPrinter v1.0");
    createUI();
    PrinterJob pj = PrinterJob.getPrinterJob();
    mPageFormat = pj.defaultPage();
    setVisible(true);
  }
  protected void createUI() {
    setSize(300, 300);
    center();
    // Add the menu bar.
    JMenuBar mb = new JMenuBar();
    JMenu file = new JMenu("File", true);
    file.add(new FilePrintAction()).setAccelerator(
        KeyStroke.getKeyStroke(KeyEvent.VK_P, Event.CTRL_MASK));
    file.add(new FilePageSetupAction()).setAccelerator(
        KeyStroke.getKeyStroke(KeyEvent.VK_P, Event.CTRL_MASK
            | Event.SHIFT_MASK));
    file.addSeparator();
    file.add(new FileQuitAction()).setAccelerator(
        KeyStroke.getKeyStroke(KeyEvent.VK_Q, Event.CTRL_MASK));
    mb.add(file);
    setJMenuBar(mb);
    // Add the contents of the window.
    getContentPane().add(new PatchworkComponent());
    // Exit the application when the window is closed.
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
  }
  protected void center() {
    Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
    Dimension us = getSize();
    int x = (screen.width - us.width) / 2;
    int y = (screen.height - us.height) / 2;
    setLocation(x, y);
  }
  public class FilePrintAction extends AbstractAction {
    public FilePrintAction() {
      super("Print");
    }
    public void actionPerformed(ActionEvent ae) {
      PrinterJob pj = PrinterJob.getPrinterJob();
      ComponentPrintable cp = new ComponentPrintable(getContentPane());
      pj.setPrintable(cp, mPageFormat);
      if (pj.printDialog()) {
        try {
          pj.print();
        } catch (PrinterException e) {
          System.out.println(e);
        }
      }
    }
  }
  public class FilePageSetupAction extends AbstractAction {
    public FilePageSetupAction() {
      super("Page setup...");
    }
    public void actionPerformed(ActionEvent ae) {
      PrinterJob pj = PrinterJob.getPrinterJob();
      mPageFormat = pj.pageDialog(mPageFormat);
    }
  }
  public class FileQuitAction extends AbstractAction {
    public FileQuitAction() {
      super("Quit");
    }
    public void actionPerformed(ActionEvent ae) {
      System.exit(0);
    }
  }
}
class PatchworkComponent extends JComponent implements Printable {
  private float mSide = 36;
  private float mOffset = 36;
  private int mColumns = 8;
  private int mRows = 4;
  private String mString = "Java Source and Support";
  private Font mFont = new Font("Serif", Font.PLAIN, 64);
  private Paint mHorizontalGradient, mVerticalGradient;
  public PatchworkComponent() {
    float x = mOffset;
    float y = mOffset;
    float halfSide = mSide / 2;
    float x0 = x + halfSide;
    float y0 = y;
    float x1 = x + halfSide;
    float y1 = y + (mRows * mSide);
    mVerticalGradient = new GradientPaint(x0, y0, Color.darkGray, x1, y1,
        Color.lightGray, true);
    x0 = x;
    y0 = y + halfSide;
    x1 = x + (mColumns * mSide);
    y1 = y + halfSide;
    mHorizontalGradient = new GradientPaint(x0, y0, Color.darkGray, x1, y1,
        Color.lightGray, true);
  }
  public PatchworkComponent(String s) {
    this();
    mString = s;
  }
  public void paintComponent(Graphics g) {
    Graphics2D g2 = (Graphics2D) g;
    g2.rotate(Math.PI / 24, mOffset, mOffset);
    for (int row = 0; row < mRows; row++) {
      for (int column = 0; column < mColumns; column++) {
        float x = column * mSide + mOffset;
        float y = row * mSide + mOffset;
        if (((column + row) % 2) == 0)
          g2.setPaint(mVerticalGradient);
        else
          g2.setPaint(mHorizontalGradient);
        Rectangle2D r = new Rectangle2D.Float(x, y, mSide, mSide);
        g2.fill(r);
      }
    }
    FontRenderContext frc = g2.getFontRenderContext();
    float width = (float) mFont.getStringBounds(mString, frc).getWidth();
    LineMetrics lm = mFont.getLineMetrics(mString, frc);
    float x = ((mColumns * mSide) - width) / 2 + mOffset;
    float y = ((mRows * mSide) + lm.getAscent()) / 2 + mOffset;
    g2.setFont(mFont);
    g2.setPaint(Color.white);
    g2.drawString(mString, x, y);
  }
  public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
    if (pageIndex != 0)
      return NO_SUCH_PAGE;
    paintComponent(g);
    return PAGE_EXISTS;
  }
}
class ComponentPrintable implements Printable {
  private Component mComponent;
  public ComponentPrintable(Component c) {
    mComponent = c;
  }
  public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
    if (pageIndex > 0)
      return NO_SUCH_PAGE;
    Graphics2D g2 = (Graphics2D) g;
    g2.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
    boolean wasBuffered = disableDoubleBuffering(mComponent);
    mComponent.paint(g2);
    restoreDoubleBuffering(mComponent, wasBuffered);
    return PAGE_EXISTS;
  }
  private boolean disableDoubleBuffering(Component c) {
    if (c instanceof JComponent == false)
      return false;
    JComponent jc = (JComponent) c;
    boolean wasBuffered = jc.isDoubleBuffered();
    jc.setDoubleBuffered(false);
    return wasBuffered;
  }
  private void restoreDoubleBuffering(Component c, boolean wasBuffered) {
    if (c instanceof JComponent)
      ((JComponent) c).setDoubleBuffered(wasBuffered);
  }
}



Print the printable area outline

   
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
public class OutlinePrintable implements Printable {
  public int print(Graphics g, PageFormat pf, int pageIndex) {
    if (pageIndex != 0)
      return NO_SUCH_PAGE;
    Graphics2D g2 = (Graphics2D) g;
    Rectangle2D outline = new Rectangle2D.Double(pf.getImageableX(), pf
        .getImageableY(), pf.getImageableWidth(), pf
        .getImageableHeight());
    g2.setPaint(Color.black);
    g2.draw(outline);
    return PAGE_EXISTS;
  }
  public static void main(String[] args) {
    PrinterJob pj = PrinterJob.getPrinterJob();
    pj.setPrintable(new OutlinePrintable());
    if (pj.printDialog()) {
      try {
        pj.print();
      } catch (PrinterException e) {
        System.out.println(e);
      }
    }
  }
}



Print the text file and print preview them

   
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Event;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
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 java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Vector;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
public class FilePrinter extends JFrame {
  private PageFormat pageFormat;
  private FilePageRenderer pageRenderer;
  private String title;
  public FilePrinter() {
    super();
    init();
    PrinterJob pj = PrinterJob.getPrinterJob();
    pageFormat = pj.defaultPage();
    setVisible(true);
  }
  protected void init() {
    setSize(350, 300);
    center();
    Container content = getContentPane();
    content.setLayout(new BorderLayout());
    // Add the menu bar.
    JMenuBar mb = new JMenuBar();
    JMenu file = new JMenu("File", true);
    file.add(new FileOpenAction()).setAccelerator(
        KeyStroke.getKeyStroke(KeyEvent.VK_O, Event.CTRL_MASK));
    file.add(new FilePrintAction()).setAccelerator(
        KeyStroke.getKeyStroke(KeyEvent.VK_P, Event.CTRL_MASK));
    file.add(new FilePageSetupAction()).setAccelerator(
        KeyStroke.getKeyStroke(KeyEvent.VK_P, Event.CTRL_MASK
            | Event.SHIFT_MASK));
    file.addSeparator();
    file.add(new FileQuitAction()).setAccelerator(
        KeyStroke.getKeyStroke(KeyEvent.VK_Q, Event.CTRL_MASK));
    mb.add(file);
    JMenu page = new JMenu("Page", true);
    page.add(new PageNextPageAction()).setAccelerator(
        KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, 0));
    page.add(new PagePreviousPageAction()).setAccelerator(
        KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, 0));
    mb.add(page);
    setJMenuBar(mb);
    getContentPane().setLayout(new BorderLayout());
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
  }
  protected void center() {
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    Dimension frameSize = getSize();
    int x = (screenSize.width - frameSize.width) / 2;
    int y = (screenSize.height - frameSize.height) / 2;
    setLocation(x, y);
  }
  public void showTitle() {
    int currentPage = pageRenderer.getCurrentPage() + 1;
    int numPages = pageRenderer.getNumPages();
    setTitle(title + " - page " + currentPage + " of " + numPages);
  }
  public class FileOpenAction extends AbstractAction {
    public FileOpenAction() {
      super("Open...");
    }
    public void actionPerformed(ActionEvent ae) {
      // Pop up a file dialog.
      JFileChooser fc = new JFileChooser(".");
      int result = fc.showOpenDialog(FilePrinter.this);
      if (result != 0) {
        return;
      }
      java.io.File f = fc.getSelectedFile();
      if (f == null) {
        return;
      }
      // Load the specified file.
      try {
        pageRenderer = new FilePageRenderer(f, pageFormat);
        title = "[" + f.getName() + "]";
        showTitle();
        JScrollPane jsp = new JScrollPane(pageRenderer);
        getContentPane().removeAll();
        getContentPane().add(jsp, BorderLayout.CENTER);
        validate();
      } catch (java.io.IOException ioe) {
        System.out.println(ioe);
      }
    }
  }
  public static void main(String[] args) {
    new FilePrinter();
  }
  public class FilePrintAction extends AbstractAction {
    public FilePrintAction() {
      super("Print");
    }
    public void actionPerformed(ActionEvent ae) {
      PrinterJob pj = PrinterJob.getPrinterJob();
      pj.setPrintable(pageRenderer, pageFormat);
      if (pj.printDialog()) {
        try {
          pj.print();
        } catch (PrinterException e) {
          System.out.println(e);
        }
      }
    }
  }
  public class FilePageSetupAction extends AbstractAction {
    public FilePageSetupAction() {
      super("Page setup...");
    }
    public void actionPerformed(ActionEvent ae) {
      PrinterJob pj = PrinterJob.getPrinterJob();
      pageFormat = pj.pageDialog(pageFormat);
      if (pageRenderer != null) {
        pageRenderer.pageInit(pageFormat);
        showTitle();
      }
    }
  }
  public class FileQuitAction extends AbstractAction {
    public FileQuitAction() {
      super("Quit");
    }
    public void actionPerformed(ActionEvent ae) {
      System.exit(0);
    }
  }
  public class PageNextPageAction extends AbstractAction {
    public PageNextPageAction() {
      super("Next page");
    }
    public void actionPerformed(ActionEvent ae) {
      if (pageRenderer != null)
        pageRenderer.nextPage();
      showTitle();
    }
  }
  public class PagePreviousPageAction extends AbstractAction {
    public PagePreviousPageAction() {
      super("Previous page");
    }
    public void actionPerformed(ActionEvent ae) {
      if (pageRenderer != null)
        pageRenderer.previousPage();
      showTitle();
    }
  }
  class FilePageRenderer extends JComponent implements Printable {
    private int currentPageIndex;
    private Vector lineVector;
    private Vector pageVector;
    private Font font;
    private int fontSize;
    private Dimension preferredSize;
    public FilePageRenderer(File file, PageFormat pageFormat)
        throws IOException {
      fontSize = 12;
      font = new Font("Serif", Font.PLAIN, fontSize);
      BufferedReader in = new BufferedReader(new FileReader(file));
      String line;
      lineVector = new Vector();
      while ((line = in.readLine()) != null)
        lineVector.addElement(line);
      in.close();
      pageInit(pageFormat);
    }
    public void pageInit(PageFormat pageFormat) {
      currentPageIndex = 0;
      pageVector = new Vector();
      float y = fontSize;
      Vector page = new Vector();
      for (int i = 0; i < lineVector.size(); i++) {
        String line = (String) lineVector.elementAt(i);
        page.addElement(line);
        y += fontSize;
        if (y + fontSize * 2 > pageFormat.getImageableHeight()) {
          y = 0;
          pageVector.addElement(page);
          page = new Vector();
        }
      }
      if (page.size() > 0)
        pageVector.addElement(page);
      preferredSize = new Dimension((int) pageFormat.getImageableWidth(),
          (int) pageFormat.getImageableHeight());
      repaint();
    }
    public void paintComponent(Graphics g) {
      Graphics2D g2 = (Graphics2D) g;
      java.awt.geom.Rectangle2D r = new java.awt.geom.Rectangle2D.Float(0, 0,
          preferredSize.width, preferredSize.height);
      g2.setPaint(Color.white);
      g2.fill(r);
      Vector page = (Vector) pageVector.elementAt(currentPageIndex);
      g2.setFont(font);
      g2.setPaint(Color.black);
      float x = 0;
      float y = fontSize;
      for (int i = 0; i < page.size(); i++) {
        String line = (String) page.elementAt(i);
        if (line.length() > 0)
          g2.drawString(line, (int) x, (int) y);
        y += fontSize;
      }
    }
    public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
      if (pageIndex >= pageVector.size())
        return NO_SUCH_PAGE;
      int savedPage = currentPageIndex;
      currentPageIndex = pageIndex;
      Graphics2D g2 = (Graphics2D) g;
      g2.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
      paint(g2);
      currentPageIndex = savedPage;
      return PAGE_EXISTS;
    }
    public Dimension getPreferredSize() {
      return preferredSize;
    }
    public int getCurrentPage() {
      return currentPageIndex;
    }
    public int getNumPages() {
      return pageVector.size();
    }
    public void nextPage() {
      if (currentPageIndex < pageVector.size() - 1)
        currentPageIndex++;
      repaint();
    }
    public void previousPage() {
      if (currentPageIndex > 0)
        currentPageIndex--;
      repaint();
    }
  }  
}



Print to the standard output

   
/*
 * Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002.
 * All rights reserved. Software written by Ian F. Darwin and others.
 * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
 * 
 * Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee
 * cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s,
 * pioneering role in inventing and promulgating (and standardizing) the Java 
 * language and environment is gratefully acknowledged.
 * 
 * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
 * inventing predecessor languages C and C++ is also gratefully acknowledged.
 */
import java.io.PrintWriter;
/** Print to the standard output */
public class PrintStandardOutput {
  public static void main(String[] args) {
    // Just a String to include in printouts.
    String myAnswer = "No, and that"s final,";
    // Print to standard output
    System.out.println("Hello World of Java");
    // Print several things concatendated.
    System.out.println("The answer is " + myAnswer + " at this time.");
    // Print to standard output using a Writer
    PrintWriter pw = new PrintWriter(System.out);
    pw.println("The answer is " + myAnswer + " at this time.");
    // Caveat printing ints and chars together
    int i = 42;
    pw.println(i + "=" + " the answer."); // WRONG
    pw.println("Note: " + i + "=" + " the answer."); // OK
    // Some of the workarounds for the caveat above:
    pw.println(i + "=" + " the answer."); // using quotes
    pw.println(i + ("=" + " the answer.")); // parenthesis
    pw.close(); // If you open it, you close it.
  }
}



Prompting for a Printer

   
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.ServiceUI;
import javax.print.SimpleDoc;
import javax.print.attribute.DocAttributeSet;
import javax.print.attribute.HashDocAttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.event.PrintJobAdapter;
import javax.print.event.PrintJobEvent;
import javax.print.event.PrintJobListener;
public class OneFourDialog {
  public static void main(String args[]) throws Exception {
    String filename = args[0];
    PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
    DocFlavor flavor = DocFlavor.INPUT_STREAM.GIF;
    PrintService printService[] = PrintServiceLookup.lookupPrintServices(
        flavor, pras);
    PrintService defaultService = PrintServiceLookup
        .lookupDefaultPrintService();
    PrintService service = ServiceUI.printDialog(null, 200, 200,
        printService, defaultService, DocFlavor.INPUT_STREAM.GIF, pras);
    if (service != null) {
      DocPrintJob job = service.createPrintJob();
      PrintJobListener listener = new PrintJobAdapter() {
        public void printDataTransferCompleted(PrintJobEvent e) {
          System.exit(0);
        }
      };
      job.addPrintJobListener(listener);
      FileInputStream fis = new FileInputStream(filename);
      DocAttributeSet das = new HashDocAttributeSet();
      Doc doc = new SimpleDoc(fis, flavor, das);
      job.print(doc, pras);
      Thread.sleep(10000);
    }
  }
}



Scribble

   
/*
 * Copyright (c) 2000 David Flanagan.  All rights reserved.
 * This code is from the book Java Examples in a Nutshell, 2nd 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.
 * You may distribute it non-commercially as long as you retain this notice.
 * For a commercial use license, or to purchase the book (recommended),
 * visit http://www.davidflanagan.ru/javaexamples2.
 */
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ruponent;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;
import javax.swing.border.BevelBorder;
/**
 * This JFrame subclass is a simple "paint" application.
 */
public class Scribble extends JFrame {
  /**
   * The main method instantiates an instance of the class, sets it size, and
   * makes it visible on the screen
   */
  public static void main(String[] args) {
    Scribble scribble = new Scribble();
    scribble.setSize(500, 300);
    scribble.setVisible(true);
  }
  // The scribble application relies on the ScribblePane2 component developed
  // earlier. This field holds the ScribblePane2 instance it uses.
  ScribblePane2 scribblePane;
  /**
   * This constructor creates the GUI for this application.
   */
  public Scribble() {
    super("Scribble"); // Call superclass constructor and set window title
    // Handle window close requests
    this.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    // All content of a JFrame (except for the menubar) goes in the
    // Frame"s internal "content pane", not in the frame itself.
    // The same is true for JDialog and similar top-level containers.
    Container contentPane = this.getContentPane();
    // Specify a layout manager for the content pane
    contentPane.setLayout(new BorderLayout());
    // Create the main scribble pane component, give it a border, and
    // a background color, and add it to the content pane
    scribblePane = new ScribblePane2();
    scribblePane.setBorder(new BevelBorder(BevelBorder.LOWERED));
    scribblePane.setBackground(Color.white);
    contentPane.add(scribblePane, BorderLayout.CENTER);
    // Create a menubar and add it to this window. Note that JFrame
    // handles menus specially and has a special method for adding them
    // outside of the content pane.
    JMenuBar menubar = new JMenuBar(); // Create a menubar
    this.setJMenuBar(menubar); // Display it in the JFrame
    // Create menus and add to the menubar
    JMenu filemenu = new JMenu("File");
    JMenu colormenu = new JMenu("Color");
    menubar.add(filemenu);
    menubar.add(colormenu);
    // Create some Action objects for use in the menus and toolbars.
    // An Action combines a menu title and/or icon with an ActionListener.
    // These Action classes are defined as inner classes below.
    Action clear = new ClearAction();
    Action quit = new QuitAction();
    Action black = new ColorAction(Color.black);
    Action red = new ColorAction(Color.red);
    Action blue = new ColorAction(Color.blue);
    Action select = new SelectColorAction();
    // Populate the menus using Action objects
    filemenu.add(clear);
    filemenu.add(quit);
    colormenu.add(black);
    colormenu.add(red);
    colormenu.add(blue);
    colormenu.add(select);
    // Now create a toolbar, add actions to it, and add it to the
    // top of the frame (where it appears underneath the menubar)
    JToolBar toolbar = new JToolBar();
    toolbar.add(clear);
    toolbar.add(select);
    toolbar.add(quit);
    contentPane.add(toolbar, BorderLayout.NORTH);
    // Create another toolbar for use as a color palette and add to
    // the left side of the window.
    JToolBar palette = new JToolBar();
    palette.add(black);
    palette.add(red);
    palette.add(blue);
    palette.setOrientation(SwingConstants.VERTICAL);
    contentPane.add(palette, BorderLayout.WEST);
  }
  /** This inner class defines the "clear" action that clears the scribble */
  class ClearAction extends AbstractAction {
    public ClearAction() {
      super("Clear"); // Specify the name of the action
    }
    public void actionPerformed(ActionEvent e) {
      scribblePane.clear();
    }
  }
  /** This inner class defines the "quit" action to quit the program */
  class QuitAction extends AbstractAction {
    public QuitAction() {
      super("Quit");
    }
    public void actionPerformed(ActionEvent e) {
      // Use JOptionPane to confirm that the user really wants to quit
      int response = JOptionPane.showConfirmDialog(Scribble.this,
          "Really Quit?");
      if (response == JOptionPane.YES_OPTION)
        System.exit(0);
    }
  }
  /**
   * This inner class defines an Action that sets the current drawing color of
   * the ScribblePane2 component. Note that actions of this type have icons
   * rather than labels
   */
  class ColorAction extends AbstractAction {
    Color color;
    public ColorAction(Color color) {
      this.color = color;
      putValue(Action.SMALL_ICON, new ColorIcon(color)); // specify icon
    }
    public void actionPerformed(ActionEvent e) {
      scribblePane.setColor(color); // Set current drawing color
    }
  }
  /**
   * This inner class implements Icon to draw a solid 16x16 block of the
   * specified color. Most icons are instances of ImageIcon, but since we"re
   * only using solid colors here, it is easier to implement this custom Icon
   * type
   */
  static class ColorIcon implements Icon {
    Color color;
    public ColorIcon(Color color) {
      this.color = color;
    }
    // These two methods specify the size of the icon
    public int getIconHeight() {
      return 16;
    }
    public int getIconWidth() {
      return 16;
    }
    // This method draws the icon
    public void paintIcon(Component c, Graphics g, int x, int y) {
      g.setColor(color);
      g.fillRect(x, y, 16, 16);
    }
  }
  /**
   * This inner class defines an Action that uses JColorChooser to allow the
   * user to select a drawing color
   */
  class SelectColorAction extends AbstractAction {
    public SelectColorAction() {
      super("Select Color...");
    }
    public void actionPerformed(ActionEvent e) {
      Color color = JColorChooser.showDialog(Scribble.this,
          "Select Drawing Color", scribblePane.getColor());
      if (color != null)
        scribblePane.setColor(color);
    }
  }
}
/*
 * Copyright (c) 2000 David Flanagan. All rights reserved. This code is from the
 * book Java Examples in a Nutshell, 2nd 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. You may distribute it non-commercially as
 * long as you retain this notice. For a commercial use license, or to purchase
 * the book (recommended), visit http://www.davidflanagan.ru/javaexamples2.
 */
/**
 * A simple JPanel subclass that uses event listeners to allow the user to
 * scribble with the mouse. Note that scribbles are not saved or redrawn.
 */
class ScribblePane2 extends JPanel {
  public ScribblePane2() {
    // Give the component a preferred size
    setPreferredSize(new Dimension(450, 200));
    // Register a mouse event handler defined as an inner class
    // Note the call to requestFocus(). This is required in order for
    // the component to receive key events.
    addMouseListener(new MouseAdapter() {
      public void mousePressed(MouseEvent e) {
        moveto(e.getX(), e.getY()); // Move to click position
        requestFocus(); // Take keyboard focus
      }
    });
    // Register a mouse motion event handler defined as an inner class
    // By subclassing MouseMotionAdapter rather than implementing
    // MouseMotionListener, we only override the method we"re interested
    // in and inherit default (empty) implementations of the other methods.
    addMouseMotionListener(new MouseMotionAdapter() {
      public void mouseDragged(MouseEvent e) {
        lineto(e.getX(), e.getY()); // Draw to mouse position
      }
    });
    // Add a keyboard event handler to clear the screen on key "C"
    addKeyListener(new KeyAdapter() {
      public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_C)
          clear();
      }
    });
  }
  /** These are the coordinates of the the previous mouse position */
  protected int last_x, last_y;
  /** Remember the specified point */
  public void moveto(int x, int y) {
    last_x = x;
    last_y = y;
  }
  /** Draw from the last point to this point, then remember new point */
  public void lineto(int x, int y) {
    Graphics g = getGraphics(); // Get the object to draw with
    g.setColor(color); // Tell it what color to use
    g.drawLine(last_x, last_y, x, y); // Tell it what to draw
    moveto(x, y); // Save the current point
  }
  /**
   * Clear the drawing area, using the component background color. This method
   * works by requesting that the component be redrawn. Since this component
   * does not have a paintComponent() method, nothing will be drawn. However,
   * other parts of the component, such as borders or sub-components will be
   * drawn correctly.
   */
  public void clear() {
    repaint();
  }
  /** This field holds the current drawing color property */
  Color color = Color.black;
  /** This is the property "setter" method for the color property */
  public void setColor(Color color) {
    this.color = color;
  }
  /** This is the property "getter" method for the color property */
  public Color getColor() {
    return color;
  }
}



Setting the Orientation of a Printed Page

   
import java.awt.print.PageFormat;
import java.awt.print.PrinterJob;
public class Main {
  public static void main(String[] argv) throws Exception {
    PrinterJob pjob = PrinterJob.getPrinterJob();
    PageFormat pf = pjob.defaultPage();
    pf.setOrientation(PageFormat.PORTRAIT);
    pf.setOrientation(PageFormat.LANDSCAPE);
    // pjob.setPrintable(printable, pf);
    pjob.print();
  }
}



Shapes Print

   
import java.awt.BorderLayout;
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.event.WindowListener;
import java.awt.geom.RoundRectangle2D;
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.JPanel;
public class ShapesPrint extends JPanel implements Printable, ActionListener {
  final static JButton button = new JButton("Print");
  public ShapesPrint() {
    button.addActionListener(this);
  }
  public void actionPerformed(ActionEvent e) {
    if (e.getSource() instanceof JButton) {
      PrinterJob printJob = PrinterJob.getPrinterJob();
      printJob.setPrintable(this);
      if (printJob.printDialog()) {
        try {
          printJob.print();
        } catch (Exception ex) {
          ex.printStackTrace();
        }
      }
    }
  }
  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;
    drawShapes(g2);
  }
  public void drawShapes(Graphics2D g2) {
    g2.fill(new RoundRectangle2D.Double(10, 10, 200, 200, 10, 10));
  }
  public int print(Graphics g, PageFormat pf, int pi) throws PrinterException {
    if (pi >= 1) {
      return Printable.NO_SUCH_PAGE;
    }
    drawShapes((Graphics2D) g);
    return Printable.PAGE_EXISTS;
  }
  public static void main(String s[]) {
    WindowListener l = new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
      public void windowClosed(WindowEvent e) {
        System.exit(0);
      }
    };
    JFrame f = new JFrame();
    f.addWindowListener(l);
    JPanel panel = new JPanel();
    panel.add(button);
    f.getContentPane().add(BorderLayout.SOUTH, panel);
    f.getContentPane().add(BorderLayout.CENTER, new ShapesPrint());
    f.setSize(580, 500);
    f.show();
  }
}



Simple Book for printing

   
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
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.event.WindowListener;
import java.awt.geom.RoundRectangle2D;
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;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class SimpleBook extends JPanel implements ActionListener {
  final static JButton button = new JButton("Print");
  public SimpleBook() {
    button.addActionListener(this);
  }
  public void actionPerformed(ActionEvent e) {
    PrinterJob job = PrinterJob.getPrinterJob();
    PageFormat landscape = job.defaultPage();
    landscape.setOrientation(PageFormat.LANDSCAPE);
    Book bk = new Book();
    bk.append(new DefaultPage(), job.defaultPage());
    bk.append(new PaintContent(), landscape);
    job.setPageable(bk);
    if (job.printDialog()) {
      try {
        job.print();
      } catch (Exception exc) {
      }
    }
  }
  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;
    drawShapes(g2);
  }
  static void drawShapes(Graphics2D g2) {
    g2.fill(new RoundRectangle2D.Double(10, 10, 200, 200, 10, 10));
  }
  public static void main(String[] args) {
    WindowListener l = new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
      public void windowClosed(WindowEvent e) {
        System.exit(0);
      }
    };
    JFrame f = new JFrame();
    f.addWindowListener(l);
    JPanel panel = new JPanel();
    panel.add(button);
    f.getContentPane().add(BorderLayout.SOUTH, panel);
    f.getContentPane().add(BorderLayout.CENTER, new SimpleBook());
    f.setSize(775, 450);
    f.show();
  }
}
class DefaultPage implements Printable {
  Font fnt = new Font("Helvetica-Bold", Font.PLAIN, 48);
  public int print(Graphics g, PageFormat pf, int pageIndex)
      throws PrinterException {
    g.setFont(fnt);
    g.setColor(Color.black);
    g.drawString("Sample Shapes", 100, 200);
    return Printable.PAGE_EXISTS;
  }
}
class PaintContent implements Printable {
  public int print(Graphics g, PageFormat pf, int pageIndex)
      throws PrinterException {
    SimpleBook.drawShapes((Graphics2D) g);
    return Printable.PAGE_EXISTS;
  }
}



Simplest SWT Print Example

   
/**
 * Class: Example1
 * <p>
 * 
 * @author Jean-Pierre Dube <jpdube@videotron.ca>
 * @version 1.0
 * @since 1.0
 * @see Printable
 */
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterJob;
public class JavaWorldPrintExample1 implements Printable {
  public static void main(String[] args) {
    JavaWorldPrintExample1 example1 = new JavaWorldPrintExample1();
    System.exit(0);
  }
  //--- Private instances declarations
  private final double INCH = 72;
  /**
   * Constructor: Example1
   * <p>
   *  
   */
  public JavaWorldPrintExample1() {
    //--- Create a printerJob object
    PrinterJob printJob = PrinterJob.getPrinterJob();
    //--- Set the printable class to this one since we
    //--- are implementing the Printable interface
    printJob.setPrintable(this);
    //--- Show a print dialog to the user. If the user
    //--- click the print button, then print otherwise
    //--- cancel the print job
    if (printJob.printDialog()) {
      try {
        printJob.print();
      } catch (Exception PrintException) {
        PrintException.printStackTrace();
      }
    }
  }
  /**
   * Method: print
   * <p>
   * 
   * This class is responsible for rendering a page using the provided
   * parameters. The result will be a grid where each cell will be half an
   * inch by half an inch.
   * 
   * @param g
   *            a value of type Graphics
   * @param pageFormat
   *            a value of type PageFormat
   * @param page
   *            a value of type int
   * @return a value of type int
   */
  public int print(Graphics g, PageFormat pageFormat, int page) {
    int i;
    Graphics2D g2d;
    Line2D.Double line = new Line2D.Double();
    //--- Validate the page number, we only print the first page
    if (page == 0) {
      //--- Create a graphic2D object a set the default parameters
      g2d = (Graphics2D) g;
      g2d.setColor(Color.black);
      //--- Translate the origin to be (0,0)
      g2d.translate(pageFormat.getImageableX(), pageFormat
          .getImageableY());
      //--- Print the vertical lines
      for (i = 0; i < pageFormat.getWidth(); i += INCH / 2) {
        line.setLine(i, 0, i, pageFormat.getHeight());
        g2d.draw(line);
      }
      //--- Print the horizontal lines
      for (i = 0; i < pageFormat.getHeight(); i += INCH / 2) {
        line.setLine(0, i, pageFormat.getWidth(), i);
        g2d.draw(line);
      }
      return (PAGE_EXISTS);
    } else
      return (NO_SUCH_PAGE);
  }
} //Example1



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) {
    }
  }
}



The Printing code which implements Printable

   
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.swing.JComponent;
public class BasicPrint extends JComponent implements Printable {
  public int print(Graphics g, PageFormat pf, int pageIndex) {
    if (pageIndex > 0) {
      return Printable.NO_SUCH_PAGE;
    }
    Graphics2D g2d = (Graphics2D) g;
    g2d.translate(pf.getImageableX(), pf.getImageableY());
    drawGraphics(g2d, pf);
    return Printable.PAGE_EXISTS;
  }
  public void drawGraphics(Graphics2D g2d,PageFormat pf){
    
  }
  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) {
    }
  }
}