|
J2Printer |
|
J2PrinterWorks provides the base class J2Printer for managing the Java printing process. J2Printer implements the complete process for printing a Java Pageable. Pageable is the Java interface for a set of printable pages. The J2Printer class supports such features as headers, footers, and margins, display of page setup, print preview, and print dialogs, printing in a background thread, and detecting print progress events.
J2PrinterWorks provides 7 classes for creating Pageables (each described in their own sections): J2TextPrinter (for JTextPane, JEditorPane, and JTextArea), J2TablePrinter (for JTable), J2TreePrinter (for JTree), J2ListPrinter (for JList), J2PanelPrinter (for JPanel), J2ComponentPrinter (for any Java Component), and J2FlowPrinter (for a sequence of Flowables). For example, the following code creates a Pageable instance for a JTextPane:
J2TextPrinter yourPageable = new J2TextPrinter(yourJTextPane);
You may also create your own Pageables by implementing the Java Pageable interface yourself.
Having created yourPageable, printing it with J2PrinterWorks is accomplished by instantiating a J2Printer instance, giving it your Pageable, and telling it to print, i.e.:
J2Printer printer = new
J2Printer();
printer.setPageable(yourPageable);
printer.print();
The J2Printer
print method also takes Pageable as an argument, so shorthand
alternatives are possible such as:
new
J2Printer().print(yourPageable);
or even:
new
J2Printer().print(new J2TextPrinter(yourJTextPane));
J2Printer can also print a series of Pageables as a single document using an addPageable method:
J2Printer printer = new J2Printer();
printer.setPageable(pageable1);
printer.addPageable(pageable2);
printer.addPageable(pageable3);
printer.print();
This sequence groups three Pageables together in a single Pageable, implemented using the Java class Book. The result is that the individual pages from the three Pageables will be printed back-to-back in one document.
Having used setPageable and/or addPageable
to specify some Pageables, you can use clearPageable() to
reset to an empty overall document. Also, note that since the
J2Printer instance starts with an empty overall document, you could
have used a addPageable in place of the the first setPageable
call above.
J2Printer contains a number of methods for controlling the printing process itself. Some of the more commonly used are these:
cancelPrinting ()
Cancel the
current printing job
setNumberOfCopies (int numberOfCopies)
Sets number of
copies to be printed.
setPaperSize (double paperW, double paperH)
Sets the paper
width and height when paper viewed in PORTRAIT.
setPrintDialogUsed (boolean printDialogUsed)
Sets whether to
show a print dialog before printing.
setPrintJobName (String printJobName)
Sets the print
job name that appears in the system print monitor.
setSeparatePrintThread (boolean separatePrintThread)
Sets whether to
print from a separate thread (instead of from the thread that called
the print method).
J2Printer also has methods for setting the headers, footers, margins, orientation, and scale for the Pageable that it will print. The J2Printer values for these define the "global" (default) values used for the overall document, which will be used unless an individual Pageable specifies its own "local" values (see "Global vs. local values" section below).
The following sections describe the individual methods used to
control these features.
Headers and footers, boxes and lines
These methods let you define left, center, and right headers and footers. Any of these can be a String specifying a single line in a single font, or a JLabel specifying multiple lines, rich text, and Images. Any of these can contain page numbering and date and time formatting (see Javadoc descriptions for the header and footer methods). Headers and footers can be different on the first page vs. the rest of the pages. Headers and/or footers areas can also be surrounded by a box, separated from the body by a line, or neither of these.
If you wish to have no headers (and/or no footers) and have the body of your document use this space, set the left, center, and right headers (and/or footers) to each be the empty String (""). In this case, J2PrinterWorks will automatically omit drawing the headers (and/or footers), the box or line surrounding them, and the gap separating them from the body, and instead use this extra space for the body of the document.
NOTE: In the current version of J2PrinterWorks, there is nothing to prevent using too long Strings or JLabels in your headers or footers and as a consequence having them overlap or extend beyond the specified margins or outside the boxes and lines.
The main header and footer methods are:
setLeftHeader (java.lang.Object leftHeader)
Sets the left
header using either a String or JLabel. There are similar methods
for setCenterHeader and setRightHeader, as well as
for setLeftFooter , setCenterFooter, and setRightFooter
.
setHeaderStyle (int style)
Sets header
style (BOX, LINE, or NONE). There is a similar method for
setFooterStyle .
setHeaderFont (java.awt.Font font)
Sets the font
for printing the headers when these are specified using a String.
There is a similar method for
setFooterFont .
setGapAboveFooter (double gapAboveFooter)
Sets the gap
between the bottom of the last line of body and the top of the footer
in inches. There is a similar method for
setGapBelowHeader .
Any of the above methods can be specified with an additional argument to separately control whether the settings apply to the first page vs. the remaining pages, for example:
setLeftHeader (int which, java.lang.Object leftHeader)
Sets the left
footer for either page 1 (FIRST) or pages 2...n (REST) using a String
or JLabel.
Margins
You can control the top, bottom, left, and right margins of your document. These are specified from the edge of the page, but since most printers have an "unprintable margin" area, the actual margin used will not be less than the unprintable margin.
setTopMargin (double topMargin)
Sets the top
margin (above header) in inches from the edge of the page. There
are similar methods for setBottomMargin, setLeftMargin
, and setRightMargin .
Orientation and scale
You can control the printing orientation on the page using the following method:
setOrientation (int orientation)
Sets page
orientation (portrait vs. landscape vs. reverse landscape).
You can control the scale with which pages are printed by calling the method:
setScale (double scale)
Sets
magnification or minification scaling factor.
Setting the value of scale to 1.0 results in unscaled
(100%) printing.
Setting this value to greater than 1.0 or less than 1.0 will cause
magnification
or minification, respectively.
Reading and writing PageFormat instances
J2Printer prints using margin, paper size, and orientation values set using the above methods. As a convenience for developers who need a standard Java PageFormat instance with the equivalent margins, paper size, and orientation, we have provided methods to convert between J2Printer's values and PageFormat. These can be particularly useful when working with externally-defined Pageables. The methods are:
getPageFormat ()
Method for
creating a PageFormat instance based on the J2Printer margins, paper
size, & orientation.
setPageFormat (java.awt.print.PageFormat pageFormat)
Method for
setting the J2Printer margins, paper size, & orientation based on
the specified PageFormat.
Global vs. local values
Each of the individual J2PrinterWorks Pageable components such as J2TextPrinter has a parallel set of methods for setting the headers, footers, margins, orientation, and scale. The J2Printer methods set the global (overall, default) values for these properties, which are the values that will be used unless a given Pageable sets it own local value. For example:
J2Printer printer = new
J2Printer();
printer.setLeftFooter("Overall
footer"); // set global properties
J2TextPrinter textPrinter = new
J2TextPrinter(yourJTextPane);
J2TablePrinter tablePrinter =
new J2TextPrinter(yourJTable);
textPrinter.setLeftFooter("My
footer"); // set properties for this Pageable
printer.addPageable(textPrinter);
printer.addPageable(tablePrinter);
printer.print();
In this case, "My footer" will be
the value used on the textPrinter
pages, whereas "Overall footer" will be the value used on the tablePrinter pages (and any other Pageables in the document that do
not specify their own values).
Print, Page Setup, and Print Preview
dialogs
Print dialog
By default, the native OS print dialog is displayed when the J2Printer method print() is called, which allows the user to control printer selection, page range, number of copies, etc. On Windows, the native print dialog typically looks like the following:
If the J2Printer method setPrintDialogUsed(false) has been called, then no print dialog is shown when the print() method is called and instead J2PrinterWorks prints one copy of all pages on the default printer.
showPageSetupDialog ()
Method for
showing the standard Page Setup dialog.
On Windows, the native page setup dialog typically looks like the following:
Print preview dialog
J2PrinterWorks also provides its own print preview dialog which can display a preview of the document to be printed. The print preview images are rendered by the exact same code that will be used to print. On Windows, the standard J2PrinterWorks print preview dialog looks as follows:
The J2PrinterWorks print preview dialog supports buttons for first page,
last page, next page, and previous page, or the user can type in any
page number directly. The print preview dialog can display the
page images at any scale and supports buttons for zoom in and zoom out
operations as well as allowing the user to type in any desired scale
factor. The print preview dialog also can switch between one page
and two page (side-by-side) display mode. To bring up the print
preview dialog, call the following method:
setPrintPreviewPageNumber(int pageNumber)
setPrintPreviewScale(double printPreviewScale)
setPrintPreviewTwoPageDisplay(boolean twoPageDisplay)
setPrintPreviewPageSetupDialog(java.awt.Dialog dialog)
showPrintPreviewPageSetupButton(boolean showPageSetupButton)
setPageImagesMonochrome(boolean monochrome)
setPrintPreviewCloseOnPrint(int closeOnPrint)
getPrintPreviewToolBar()
Component |
Type |
Description |
0 |
JButton |
Print |
1 |
JSeparator |
|
2 |
JButton |
Page Setup |
3 |
JSeparator |
|
4 |
JButton |
First Page |
5 |
JButton |
Previous Page |
6 |
JLabel |
"Page" |
7 |
JTextField |
current page number |
8 |
JLabel |
" of " |
9 |
JLabel |
total number of pages |
10 |
JButton |
Next Page |
11 |
JButton |
Lsst Page |
12 |
JSeparator |
|
13 |
JButton |
Zoom Out |
14 |
JTextField |
scale factor |
15 |
JButton |
Zoom In |
16 |
JSeparator |
|
17 |
JButton |
One Page Display |
18 |
JButton |
Two Page Display |
19 |
JSeparator |
|
20 |
JButton |
Close |
Print to Image
J2Printer includes methods for "printing" formatted pages
at
screen resolution to an in-memory BufferedImage, suitable for
constructing
displays like the print preview dialog. There is also a
convenience
method for saving any such BufferedImage to a JPEG (.jpg) file.
The general-purpose print-to-image method is:
getPageImage
(Pageable pageable, int pageNumber,
double scale, boolean outline, boolean reusable)
This method creates a BufferedImage representation of the specified
page (1...n) of a specified Pageable at screen resolution with a given
scale factor and optional black box drawn around the outside edge of
the page. The reusable flag indicates whether to allocate a new
BufferedImage or reuse the BufferedImage space allocated in previous
calls.
saveImageToJPEG
(java.awt.image.BufferedImage image,
java.lang.String fileName)
This method will save any BufferedImage, such as ones produced by
getPageImage(), to a JPEG (.jpg) file. Such a file is
useful for inclusion in web pages, documentation, email attachments,
etc.
To control whether the page images will be displayed in color or
monochrome, the following method is available:
setPageImagesMonochrome(boolean monochrome)
Method used
in conjunction with the getPageImage methods, and thereby the print
preview dialog page images, specifying whether the images are
monochrome (gray scale) instead of color (default: false = color).
J2Printer includes a method for "printing" a complete formatted
document as a single HTML page or as an HTML slide show. In
either case the individual page images are generated as separate .jpg
files in screen resolution at the specified scale. The single
HTML page just shows the entire series of page images in one long
document. The HTML slide show consists of a set of
linked HTML pages, each containing an image of the
next page of the document. The
HTML pages are displayed in an HTML frame set with a navigation bar on
the left allowing for random access to any page. In addition,
each page image is linked to the next page, so clicking on each page of
the document goes to the next page of the document as a slide show,
whether the HTML pages are displayed in the frame set or by
themselves. To print to HTML, call the following
method:
printToHTML(java.lang.String dir,
java.lang.String file, double scale, boolean slideshow)
Utility
method for saving a facsimile of the printed document either a a single
HTML page or as a series of
HTML pages suitable for display in a browser as a slide show.
As of the J2PrinterWorks 4.2 release, the call to printToHTML honors
the setSeparatePrintThread(boolean) method, so that by default this
method executes in a background thread and fires print progress
events.
Call setSeparatePrintThread(false) in advance of calling this method if
you don't want this method to return until printing completes.
Print to PDF
J2Printer includes methods for "printing" a complete, formatted,
J2PrinterWorks document
to a .pdf file, Adobe's widely-used Portable Document Format.
printToPDF(java.lang.String file)
Utility
method for saving a facsimile of the current document to a PDF file,
suitable for viewing and/or printing by Adobe Acrobat Reader.
This "printToPDF" method requires that you
include with your program a copy of the third-party, open source,
"iText" library
downloadable from http://www.lowagie.com/iText
and available for free under MPL or LGPL licenses. J2PrinterWorks
is written so that the iText library is not required unless you wish to
call
either of the above two "printToPDF" methods and is not required to
compile the J2PrinterWorks source code.
As of the J2PrinterWorks 4.2 release, the call to printToPDF honors
the setSeparatePrintThread(boolean) method, so that by default this
method executes in a background thread and fires print progress
events. Call
setSeparatePrintThread(false) in advance of calling this method if you
don't want this method to return until printing completes.
printPDFFile(java.lang.String file)
Utility
method for printing the contents of a PDF file on the default printer
(Windows only). Uses a print dialog if isPrintDialogUsed() is
true, otherwise prints to the default printer if using J2Printer or to
the printer specified with setPrinter if using J2Printer14.
displayPDFFile(java.lang.String file)
Utility
method for displaying the contents of a PDF file using Adobe Acrobat
Reader (Windows only).
Additional capabilities
Print progress events
The J2Printer class supports a number of print progress events that can
be
used to monitor the printing process. Five of the events are
PropertyChange events corresponding to changes in five properties that
are maintained by J2Printer. The five (read-only) properties are:
NOTE: The former J2Printer method isPrinting() was renamed to isPrintingUnderway() to avoid
conflicts with the new JCompoent method isPrinting() added in JDK 1.6.
In addition, the following two events are supported without
corresponding properties:
Your program can set up a PropertyChangeListener to listen to and key off of these property state changes. Note that you need to either setSeparatePrintThread(true), which is the default, or have your PropertyChangeListener in a separate thread from the the code that calls J2Printer.print() , otherwise the print progress events will pile up and not get back to your application until printing completes.
Sample code for creating your own PropertyChangeListener would look
like:
J2Printer printer = new J2Printer();
...
printer.addPropertyChangeListener(new PrintingStatusListener());
...
class PrintingStatusListener implements
java.beans.PropertyChangeListener {
public void
propertyChange(java.beans.PropertyChangeEvent evt) {
if
(evt.getPropertyName().equals("printingUnderway")) {
if
(printer.isPrintingUnderway()) { } // printing has started
else { }
//
printing is done
}
if
(evt.getPropertyName().equals("printDialogResponse")) {
if
(printer.isPrintDialogResponse()) { } // if user said OK
else {
}
// if
user said cancel
}
Here is a complete example of using PrintingEventHandler (taken from
J2PrinterWorksTestApplication):
J2Printer printer = new J2Printer();
JLabel status = new JLabel(); // used for status report
...
printer.addPropertyChangeListener(new
MyPrintingEventHandler());
...
class MyPrintingEventHandler extends PrintingEventHandler {
int totalPages;
public void printingStart() {
showProgress("About to
print..."); // printing started
totalPages =
printer.getPageable().getNumberOfPages(); // expensive so do only once
}
public void printingDone() {
windowToFront(); // needed
prior to JDK 1.4.1 due to Bug Parade #4514422
brieflyShowProgress("Printing done");
}
public void printDialogOK() {
windowToFront(); // needed
prior to JDK 1.4.1 due to Bug Parade #4514422
showProgress("Start
printing...");
}
public void printDialogCanceled() {
windowToFront(); // needed
prior to JDK 1.4.1 due to Bug Parade #4514422
brieflyShowProgress("Printing canceled");
}
public void pageSetupDialogOK() {
brieflyShowProgress("Page setup dialog OK");
}
public void pageSetupDialogCanceled() {
brieflyShowProgress("Page setup dialog canceled");
}
public void pageStart(int pageNum) {
showProgress("Printing page
" + pageNum + " of " + totalPages);
}
public void
exceptionThrown(Exception e) {
showProgress("Got an
exception: " + e);
}
}
private void showProgress(String str) { status.setText(str); } // where
status is a JLabel
private void brieflyShowProgress(String str) {
showProgress(str);
new Thread() { public void run() {
try {
sleep(1500); } catch (Exception e) {}
SwingUtilities.invokeLater( new Runnable() { public void run() {
showProgress(" "); } } );
} }.start(); // from different thread,
wait 1 sec then erase
}
void windowToFront() { frame.toFront(); } // needed prior to JDK 1.4.1
due to Bug Parade #4514422
See the "PrintingEventHandler" section under "Utility Classes" for more examples.
Cloning
J2Printer includes a convenience method for cloning (copying) any
Object in Java. You may find it useful to print from a copy of
your components for several reasons: 1) to avoid thread safety
problems, 2) to control the appearance of your component as printed
differently from the component as displayed, or 3) to modify your
underlying component model (such as filling in missing values) before
printing. For such purposes J2Printer includes a general-purpose
clone method:
clone (java.lang.Object obj)
This method performs a "deep clone", i.e., all contained classes are recursively cloned as well. Upon return, you need to cast the Object return value back to an Object of your type. For example, you might copy a whole component:
JTable cloneJTable = (JTable) clone(yourJTable); ;
or you might clone just the component's underlying model:
TreeModel cloneTreeModel = (TreeModel)
clone(yourJTree.getModel());
JTree newJTree = new JTree();
newJTree.setModel(cloneTreeModel);
If the object is not clonable, Java will throw a
NotSerializableException. The J2PrinterWorks clone method will
catch this exception and rethrow it as a
com.wildcrest.j2printerworks.CloneException, which is a subclass of
RuntimeException and therefore may be optionally caught.
N-up printing
J2Printer supports "N-up" printing, where multiple page
images can be
printed together on each sheet of printed paper. N-up printing
supports 1, 2, 4, 6, 9, and 16 page images per printed page, with 2 and
6 being oriented landscape on the physical page and the rest oriented
portrait. The J2Printer print preview dialog will also reflect
the current N-up setting. To select N-up printing, call the
following method:
setNup(int nup)
setStartingPageNumber(int startingPageNumber)
setParentFrame(java.awt.Component parent)
setBusyCursor(java.awt.Component parent,
boolean busy)
java.util.Locale.setDefault(java.util.Locale.FRANCE);
or by changing the locale just within J2PrinterWorks using the
static setLocale method of J2Pageable:
J2Pageable.setLocale(java.util.Locale.FRANCE);
You can use the properties files in J2PrinterWorks.jar to create
more of your own for additional desired locales by following the syntax
for specifying localized strings in these files. If you add more
properties files to your classpath (or back into J2PrinterWorks.jar),
J2PrinterWorks will find and support them. If J2PrinterWorks
can't find a properties file for the current locale, it reverts to
using English. In addition, J2Printer has a method
setPrintPreviewString which allows you to programmatically specify all
the Print Preview strings regardless of locale (see Javadoc for
J2Printer.setPrintPreviewString). You can test all the standard
J2PrinterWorks locales using the sample program
J2TextPrinterTestApplication.setDebug(boolean
debug)