001: /*
002: * $Id: PDFPrintPage.java,v 1.2 2007/12/20 18:33:33 rbair Exp $
003: *
004: * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
005: * Santa Clara, California 95054, U.S.A. All rights reserved.
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
020: */
021:
022: package com.sun.pdfview;
023:
024: import java.awt.BorderLayout;
025: import java.awt.Container;
026: import java.awt.Frame;
027: import java.awt.Graphics;
028: import java.awt.Graphics2D;
029: import java.awt.Rectangle;
030: import java.awt.event.ActionEvent;
031: import java.awt.print.PageFormat;
032: import java.awt.print.Printable;
033: import java.awt.print.PrinterException;
034: import java.awt.print.PrinterJob;
035:
036: import javax.swing.AbstractAction;
037: import javax.swing.Box;
038: import javax.swing.JButton;
039: import javax.swing.JDialog;
040: import javax.swing.JLabel;
041:
042: /**
043: * A class representing a print job for a particular PDFFile. The class
044: * maintains a status dialog as it prints, allowing the user to cancel
045: * the print job.
046: */
047: public class PDFPrintPage implements Printable {
048: /** The PDFFile to be printed */
049: private PDFFile file;
050:
051: /** The PrinterJob for this print job */
052: private PrinterJob pjob;
053:
054: /** A dialog box indicating printing status, with cancel button */
055: private JDialog pd;
056:
057: /** The text in the progress dialog indicating the current page */
058: private JLabel pagenumlabel;
059:
060: /** The cancel button in the progress dialog */
061: private JButton cancel;
062:
063: /**
064: * Create a new PDFPrintPage object for a particular PDFFile.
065: * @param file the PDFFile to be printed.
066: */
067: public PDFPrintPage(PDFFile file) {
068: this .file = file;
069: }
070:
071: /**
072: * Generates the status dialog with cancel button.
073: */
074: private void createPrintDialog() {
075: pd = new JDialog((Frame) null, "Printing...", false);
076: Container top = pd.getContentPane();
077: Box lines = Box.createVerticalBox();
078: Box line = Box.createHorizontalBox();
079: line.add(new JLabel("Now printing: "));
080: JLabel title = new JLabel("file.pdf");
081: line.add(title);
082: lines.add(line);
083:
084: line = Box.createHorizontalBox();
085: line.add(Box.createHorizontalStrut(10));
086: line.add(new JLabel("page "));
087: pagenumlabel = new JLabel("1");
088: line.add(pagenumlabel);
089: line.add(new JLabel(" of "));
090: JLabel totalpages = new JLabel(String.valueOf(file
091: .getNumPages()));
092: line.add(totalpages);
093: lines.add(line);
094:
095: top.add(lines, BorderLayout.CENTER);
096:
097: Box cancelbox = Box.createHorizontalBox();
098: cancelbox.add(Box.createHorizontalGlue());
099: cancel = new JButton(new AbstractAction("Cancel") {
100: public void actionPerformed(ActionEvent evt) {
101: doCancel();
102: }
103: });
104: cancelbox.add(cancel);
105: top.add(cancelbox, BorderLayout.SOUTH);
106: }
107:
108: /**
109: * Show the progress dialog for this print job
110: * @param pjob the PrinterJob representing the print job
111: */
112: public void show(PrinterJob pjob) {
113: this .pjob = pjob;
114: if (pd == null) {
115: createPrintDialog();
116: }
117: pd.pack();
118: pd.show();
119: }
120:
121: /**
122: * Close the progress dialog. Don't use this method to cancel
123: * the print job; use {@link #doCancel doCancel} instead.
124: */
125: public void hide() {
126: pd.dispose();
127: }
128:
129: /**
130: * Cancel the print job. Disables the cancel button, as it might
131: * take a while for the cancel to take effect.
132: */
133: public void doCancel() {
134: cancel.setEnabled(false);
135: pjob.cancel();
136: }
137:
138: // from Printable interface: prints a single page, given a Graphics
139: // to draw into, the page format, and the page number.
140: public int print(Graphics g, PageFormat format, int index)
141: throws PrinterException {
142: int pagenum = index + 1;
143:
144: // don't bother if the page number is out of range.
145: if ((pagenum >= 1) && (pagenum <= file.getNumPages())) {
146:
147: // update the page number in the progress dialog
148: if (pagenumlabel != null) {
149: pagenumlabel.setText(String.valueOf(pagenum));
150: }
151:
152: // fit the PDFPage into the printing area
153: Graphics2D g2 = (Graphics2D) g;
154: PDFPage page = file.getPage(pagenum);
155: double pwidth = format.getImageableWidth();
156: double pheight = format.getImageableHeight();
157:
158: double aspect = page.getAspectRatio();
159: double paperaspect = pwidth / pheight;
160:
161: Rectangle imgbounds;
162:
163: if (aspect > paperaspect) {
164: // paper is too tall / pdfpage is too wide
165: int height = (int) (pwidth / aspect);
166: imgbounds = new Rectangle(
167: (int) format.getImageableX(),
168: (int) (format.getImageableY() + ((pheight - height) / 2)),
169: (int) pwidth, height);
170: } else {
171: // paper is too wide / pdfpage is too tall
172: int width = (int) (pheight * aspect);
173: imgbounds = new Rectangle(
174: (int) (format.getImageableX() + ((pwidth - width) / 2)),
175: (int) format.getImageableY(), width,
176: (int) pheight);
177: }
178:
179: // debugging -- frame the page with a black border, outside the
180: // imageable region.
181: //
182: // double ix= format.getImageableX();
183: // double iy= format.getImageableY();
184: // double iw= format.getImageableWidth();
185: // double ih= format.getImageableHeight();
186: // double tw= format.getWidth();
187: // double th= format.getHeight();
188: // g2.fill(new Rectangle2D.Double(0, 0, tw, iy));
189: // g2.fill(new Rectangle2D.Double(0, 0, ix, th));
190: // g2.fill(new Rectangle2D.Double(0, iy+ih, tw, th-iy-ih));
191: // g2.fill(new Rectangle2D.Double(ix+iw, 0, tw-ix-iw, th));
192:
193: // render the page
194: PDFRenderer pgs = new PDFRenderer(page, g2, imgbounds,
195: null, null);
196: try {
197: page.waitForFinish();
198: pgs.run();
199: } catch (InterruptedException ie) {
200: }
201: return PAGE_EXISTS;
202: } else {
203: return NO_SUCH_PAGE;
204: }
205: }
206:
207: }
|