CONTENTS | PREV | NEXT | Java 2D API |
Pageable jobs are suited for applications that build an explicit representation of a document, page by page. The Book class is a convenient way to use Pageables, but you can also build your own Pageable structures if Book does not suit your needs. This section shows you how to use Book.Although slightly more involved, Pageable jobs are preferred over Printable jobs because the printing system has more flexibility. A major advantage of Pageables is that the number of pages in the document is usually known and can be displayed to the user in the print dialog box. This helps the user to confirm that the job is specified correctly or to select a range of pages for printing.
A Book represents a collection of pages. The pages in a book do not have to share the same size, orientation, or page painter. For example, a Book might contain two letter size pages in portrait orientation and a letter size page in landscape orientation.
When a Book is first constructed, it is empty. To add pages to a Book, you use the append method. This method takes a PageFormat object that defines the page's size, printable area, and orientation and a page painter that implements the Printable interface.
Multiple pages in a Book can share the same page format and painter. The append method is overloaded to enable you to add a series of pages that have the same attributes by specifying a third parameter, the number of pages.
If you don't know the total number of pages in a Book, you can pass UNKNOWN_NUMBER_OF_PAGES to the append method. The printing system will then call your page painters in order of increasing page index until one of them returns NO_SUCH_PAGE.
The setPage method can be used to change a page's page format or painter. The page to be changed is identified by a page index that indicates the page's location in the Book.
You call setPageable and pass in the Book to prepare the print job. The setPageable and setPrintable methods are mutually exclusive; that is, you should call one or the other but not both when preparing the PrinterJob.
In the following example, a Book is used to reproduce the first simple printing example. (Because this case is so simple, there is little benefit in using a Pageable job instead of a Printable job, but it illustrates the basics of using a Book.) Note that you still have to implement the Printable interface and perform page rendering in the page painter's print method.
import java.awt.*; import java.awt.print.*; public class SimplePrintBook implements Printable { private static Font fnt = new Font("Helvetica",Font.PLAIN,24); public static void main(String[] args) { // Get a PrinterJob PrinterJob job = PrinterJob.getPrinterJob(); // Set up a book Book bk = new Book(); bk.append(new SimplePrintBook(), job.defaultPage(), 5); // Pass the book to the PrinterJob job.setPageable(bk); // Put up the dialog box if (job.printDialog()) { // Print the job if the user didn't cancel printing try { job.print(); } catch (Exception e) { /* handle exception */ } } System.exit(0); } public int print(Graphics g, PageFormat pf, int pageIndex) throws PrinterException { g.setFont(fnt); g.setColor(Color.green); g.drawString("Page " + (pageIndex+1), 100, 100); return Printable.PAGE_EXISTS; } }
In the following example, two different page painters are used: one for a cover page and one for content pages. The cover page is printed in landscape mode and the contents pages are printed in portrait mode.
import java.awt.*; import java.awt.print.*; public class PrintBook { public static void main(String[] args) { // Get a PrinterJob PrinterJob job = PrinterJob.getPrinterJob(); // Create a landscape page format PageFormat pfl = job.defaultPage(); pfl.setOrientation(PageFormat.LANDSCAPE); // Set up a book Book bk = new Book(); bk.append(new PaintCover(), pfl); bk.append(new PaintContent(), job.defaultPage(), 2); // Pass the book to the PrinterJob job.setPageable(bk); // Put up the dialog box if (job.printDialog()) { // Print the job if the user didn't cancel printing try { job.print(); } catch (Exception e) { /* handle exception */ } } System.exit(0); } } class PaintCover implements Printable { Font fnt = new Font("Helvetica-Bold", Font.PLAIN, 72); public int print(Graphics g, PageFormat pf, int pageIndex) throws PrinterException { g.setFont(fnt); g.setColor(Color.black); int yc = (int) (pf.getImageableY() + pf.getImageableHeight()/2); g.drawString("Widgets, Inc.", 72, yc+36); return Printable.PAGE_EXISTS; } } class PaintContent implements Printable { public int print(Graphics g, PageFormat pf, int pageIndex) throws PrinterException { Graphics2D g2 = (Graphics2D) g; int useRed = 0; int xo = (int) pf.getImageableX(); int yo = (int) pf.getImageableY(); // Fill page with circles or squares, alternating red & green for (int x = 0; x+28 < pf.getImageableWidth(); x += 36) for (int y = 0; y+28 < pf.getImageableHeight(); y += 36) { if (useRed == 0) g.setColor(Color.red); else g.setColor(Color.green); useRed = 1 - useRed; if (pageIndex % 2 == 0) g.drawRect(xo+x+4, yo+y+4, 28, 28); else g.drawOval(xo+x+4, yo+y+4, 28, 28); } return Printable.PAGE_EXISTS; } }