Java Tutorial/2D Graphics/Print
Версия от 17:44, 31 мая 2010; (обсуждение)
Содержание
- 1 extends JuliaSet1 and overrides the print() method to demonstrate the Java 1.2 printing API
- 2 implements Printable
- 3 javax.print API and allows you to list available printers, query a named printer, print text and image files to a printer, and print to postscript files
- 4 Pagination during print
- 5 Print an image out
- 6 PrinterJob and Printable
- 7 Print Image
- 8 Printing Pages with Different Formats
- 9 Printing to a File
- 10 Print out a Swing component
- 11 The area of the actual page
- 12 The area of the printable area
- 13 Work with PrintRequestAttributeSet
extends JuliaSet1 and overrides the print() method to demonstrate the Java 1.2 printing API
/*
* Copyright (c) 2004 David Flanagan. All rights reserved.
* This code is from the book Java Examples in a Nutshell, 3nd Edition.
* It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.
* You may study, use, and modify it for any non-commercial purpose,
* including teaching and use in open-source projects.
* You may distribute it non-commercially as long as you retain this notice.
* For a commercial use license, or to purchase the book,
* please visit http://www.davidflanagan.ru/javaexamples3.
*/
//package je3.print;
import java.awt.ruponent;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.JobAttributes;
import java.awt.PageAttributes;
import java.awt.PrintJob;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
/**
* This class extends JuliaSet1 and overrides the print() method to demonstrate
* the Java 1.2 printing API.
*/
public class JuliaSet2 extends JuliaSet1 {
public JuliaSet2() {
this(.4, .4);
} // Display a different set by default
public JuliaSet2(double cx, double cy) {
super(cx, cy);
}
// This method demonstrates the Java 1.2 printing API.
// Test it using the ShowBean program.
public void print() {
// Java 1.1 used java.awt.PrintJob.
// In Java 1.2 we use java.awt.print.PrinterJob
PrinterJob job = PrinterJob.getPrinterJob();
// Alter the default page settings to request landscape mode
PageFormat page = job.defaultPage();
page.setOrientation(PageFormat.LANDSCAPE); // landscape by default
// Tell the PrinterJob what Printable object we want to print.
// PrintableComponent is defined as an inner class below
String title = "Julia set for c={" + cx + "," + cy + "}";
Printable printable = new PrintableComponent(this, title);
job.setPrintable(printable, page);
// Call the printDialog() method to give the user a chance to alter
// the printing attributes or to cancel the printing request.
if (job.printDialog()) {
// If we get here, then the user did not cancel the print job
// So start printing, displaying a dialog for errors.
try {
job.print();
} catch (PrinterException e) {
JOptionPane.showMessageDialog(this, e.toString(), "PrinterException",
JOptionPane.ERROR_MESSAGE);
}
}
}
// This inner class implements the Printable interface for an AWT component
public static class PrintableComponent implements Printable {
Component c;
String title;
public PrintableComponent(Component c, String title) {
this.c = c;
this.title = title;
}
// This method should print the specified page number to the specified
// Graphics object, abiding by the specified page format.
// The printing system will call this method repeatedly to print all
// pages of the print job. If pagenum is greater than the last page,
// it should return NO_SUCH_PAGE to indicate that it is done. The
// printing system may call this method multiple times per page.
public int print(Graphics g, PageFormat format, int pagenum) {
// This implemenation is always a single page
if (pagenum > 0)
return Printable.NO_SUCH_PAGE;
// The Java 1.2 printing API passes us a Graphics object, but we
// can always cast it to a Graphics2D object
Graphics2D g2 = (Graphics2D) g;
// Translate to accomodate the requested top and left margins.
g2.translate(format.getImageableX(), format.getImageableY());
// Figure out how big the drawing is, and how big the page
// (excluding margins) is
Dimension size = c.getSize(); // component size
double pageWidth = format.getImageableWidth(); // Page width
double pageHeight = format.getImageableHeight(); // Page height
// If the component is too wide or tall for the page, scale it down
if (size.width > pageWidth) {
double factor = pageWidth / size.width; // How much to scale
g2.scale(factor, factor); // Adjust coordinate system
pageWidth /= factor; // Adjust page size up
pageHeight /= factor;
}
if (size.height > pageHeight) { // Do the same thing for height
double factor = pageHeight / size.height;
g2.scale(factor, factor);
pageWidth /= factor;
pageHeight /= factor;
}
// Now we know the component will fit on the page. Center it by
// translating as necessary.
g2.translate((pageWidth - size.width) / 2, (pageHeight - size.height) / 2);
// Draw a line around the outside of the drawing area and label it
g2.drawRect(-1, -1, size.width + 2, size.height + 2);
g2.drawString(title, 0, -15);
// Set a clipping region so the component can"t draw outside of
// its won bounds.
g2.setClip(0, 0, size.width, size.height);
// Finally, print the component by calling its paint() method.
// This prints the background, border, and children as well.
// For swing components, if you don"t want the background, border,
// and children, then call printComponent() instead.
c.paint(g);
// Tell the PrinterJob that the page number was valid
return Printable.PAGE_EXISTS;
}
}
}
class JuliaSet1 extends JComponent {
// These constants are hard-coded for simplicity
double x1 = -1.5, y1 = -1.5, x2 = 1.5, y2 = 1.5; // Region of complex plane
int width = 400, height = 400; // Mapped to these pixels
double cx, cy; // This complex constant defines the set we display
BufferedImage image; // The image we compute
// We compute values between 0 and 63 for each point in the complex plane.
// This array holds the color values for each of those values.
static int[] colors;
static { // Static initializer for the colors[] array.
colors = new int[64];
for (int i = 0; i < colors.length; i++) {
colors[63 - i] = (i * 4 << 16) + (i * 4 << 8) + i * 4; // grayscale
// (i*4) ^ ((i * 3)<<6) ^ ((i * 7)<<13); // crazy technicolor
}
}
// No-arg constructor with default values for cx, cy.
public JuliaSet1() {
this(-1, 0);
}
// This constructor specifies the {cx,cy} constant.
// For simplicity, the other constants remain hardcoded.
public JuliaSet1(double cx, double cy) {
this.cx = cx;
this.cy = cy;
setPreferredSize(new Dimension(width, height));
computeImage();
}
// This method computes a color value for each pixel of the image
void computeImage() {
// Create the image
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// Now loop through the pixels
int i, j;
double x, y;
double dx = (x2 - x1) / width;
double dy = (y2 - y1) / height;
for (j = 0, y = y1; j < height; j++, y += dy) {
for (i = 0, x = x1; i < width; i++, x += dx) {
// For each pixel, call testPoint() to determine a value.
// Then map that value to a color and set it in the image.
// If testPoint() returns 0, the point is part of the Julia set
// and is displayed in black. If it returns 63, the point is
// displayed in white. Values in-between are displayed in
// varying shades of gray.
image.setRGB(i, j, colors[testPoint(x, y)]);
}
}
}
// This is the key method for computing Julia sets. For each point z
// in the complex plane, we repeatedly compute z = z*z + c using complex
// arithmetic. We stop iterating when the magnitude of z exceeds 2 or
// after 64 iterations. We return the number of iterations-1.
public int testPoint(double zx, double zy) {
for (int i = 0; i < colors.length; i++) {
// Compute z = z*z + c;
double newx = zx * zx - zy * zy + cx;
double newy = 2 * zx * zy + cy;
zx = newx;
zy = newy;
// Check magnitude of z and return iteration number
if (zx * zx + zy * zy > 4)
return i;
}
return colors.length - 1;
}
// This method overrides JComponent to display the julia set.
// Just scale the image to fit and draw it.
public void paintComponent(Graphics g) {
g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
}
// This method demonstrates the Java 1.1 java.awt.PrintJob printing API.
// It also demonstrates the JobAttributes and PageAttributes classes
// added in Java 1.3. Display the Julia set with ShowBean and use
// the Command menu to invoke this print command.
public void print() {
// Create some attributes objects. This is Java 1.3 stuff.
// In Java 1.1, we"d use a java.util.Preferences object instead.
JobAttributes jattrs = new JobAttributes();
PageAttributes pattrs = new PageAttributes();
// Set some example attributes: monochrome, landscape mode
pattrs.setColor(PageAttributes.ColorType.MONOCHROME);
pattrs.setOrientationRequested(PageAttributes.OrientationRequestedType.LANDSCAPE);
// Print to file by default
jattrs.setDestination(JobAttributes.DestinationType.FILE);
jattrs.setFileName("juliaset.ps");
// Look up the Frame that holds this component
Component frame = this;
while (!(frame instanceof Frame))
frame = frame.getParent();
// Get a PrintJob object to print the Julia set with.
// The getPrintJob() method displays a print dialog and allows the user
// to override and modify the default JobAttributes and PageAttributes
Toolkit toolkit = this.getToolkit();
PrintJob job = toolkit.getPrintJob((Frame) frame, "JuliaSet1", jattrs, pattrs);
// We get a null PrintJob if the user clicked cancel
if (job == null)
return;
// Get a Graphics object from the PrintJob.
// We print simply by drawing to this Graphics object.
Graphics g = job.getGraphics();
// Center the image on the page
Dimension pagesize = job.getPageDimension(); // how big is page?
Dimension panesize = this.getSize(); // how big is image?
g.translate((pagesize.width - panesize.width) / 2, // center it
(pagesize.height - panesize.height) / 2);
// Draw a box around the Julia Set and label it
g.drawRect(-1, -1, panesize.width + 2, panesize.height + 2);
g.drawString("Julia Set for c={" + cx + "," + cy + "}", 0, -15);
// Set a clipping region
g.setClip(0, 0, panesize.width, panesize.height);
// Now print the component by calling its paint method
this.paint(g);
// Finally tell the printer we"re done with the page.
// No output will be generated if we don"t call dispose() here.
g.dispose();
}
}
implements Printable
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
public class Main implements Printable {
private static Font sFont = new Font("Serif", Font.PLAIN, 64);
public int print(Graphics g, PageFormat Pf, int pageIndex) throws PrinterException {
if (pageIndex > 0)
return NO_SUCH_PAGE;
Graphics2D g2 = (Graphics2D) g;
g2.setFont(sFont);
g2.setPaint(Color.black);
g2.drawString("Save a tree!", 96, 144);
return PAGE_EXISTS;
}
public static void main(String[] args) {
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(new Main());
if (job.printDialog()) {
try {
job.print();
} catch (PrinterException e) {
}
}
System.exit(0);
}
}
javax.print API and allows you to list available printers, query a named printer, print text and image files to a printer, and print to postscript files
/*
* Copyright (c) 2004 David Flanagan. All rights reserved.
* This code is from the book Java Examples in a Nutshell, 3nd Edition.
* It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.
* You may study, use, and modify it for any non-commercial purpose,
* including teaching and use in open-source projects.
* You may distribute it non-commercially as long as you retain this notice.
* For a commercial use license, or to purchase the book,
* please visit http://www.davidflanagan.ru/javaexamples3.
*/
//package je3.print;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintException;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.StreamPrintService;
import javax.print.StreamPrintServiceFactory;
import javax.print.attribute.Attribute;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Chromaticity;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.Finishings;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.NumberUp;
import javax.print.attribute.standard.OrientationRequested;
import javax.print.attribute.standard.SheetCollate;
import javax.print.attribute.standard.Sides;
import javax.print.event.PrintJobAdapter;
import javax.print.event.PrintJobEvent;
/**
* This utility program demonstrates the javax.print API and allows you to list
* available printers, query a named printer, print text and image files to a
* printer, and print to postscript files.
*
* Usage: java Print -i inputfile [-q] [-p printer] [-ps outputfile]
* [attributes]
*/
public class Print {
public static void main(String[] args) throws IOException {
// These are values we"ll set from the command-line arguments
boolean query = false;
String printerName = null;
String inputFileName = null;
String outputFileName = null;
String outputFileType = null;
PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
// Loop through the arguments
for (int i = 0; i < args.length; i++) {
if (args[i].equals("-q"))
query = true; // Is this is query?
else if (args[i].equals("-p")) // Specific printer name
printerName = args[++i];
else if (args[i].equals("-i")) // The file to print
inputFileName = args[++i];
else if (args[i].equals("-ps")) { // Print it to this file
// Sun"s Java 1.4 implementation only supports PostScript
// output. Other implementations might offer PDF, for example.
outputFileName = args[++i];
outputFileType = "application/postscript";
}
// The rest of the arguments represent common printing attributes
else if (args[i].equals("-color")) // Request a color printer
attributes.add(Chromaticity.COLOR);
else if (args[i].equals("-landscape")) // Request landscape mode
attributes.add(OrientationRequested.LANDSCAPE);
else if (args[i].equals("-letter")) // US Letter-size paper
attributes.add(MediaSizeName.NA_LETTER);
else if (args[i].equals("-a4")) // European A4 paper
attributes.add(MediaSizeName.ISO_A4);
else if (args[i].equals("-staple")) // Request stapling
attributes.add(Finishings.STAPLE);
else if (args[i].equals("-collate")) // Collate multiple copies
attributes.add(SheetCollate.COLLATED);
else if (args[i].equals("-duplex")) // Request 2-sided
attributes.add(Sides.DUPLEX);
else if (args[i].equals("-2")) // 2 pages to a sheet
attributes.add(new NumberUp(2));
else if (args[i].equals("-copies")) // how many copies
attributes.add(new Copies(Integer.parseInt(args[++i])));
else {
System.out.println("Unknown argument: " + args[i]);
System.exit(1);
}
}
if (query) {
// If the -q argument was specified, but no printer was named,
// then list all available printers that can support the attributes
if (printerName == null)
queryServices(attributes);
// Otherwise, look for a named printer that can support the
// attributes and print its status
else
queryPrinter(printerName, attributes);
} else if (outputFileName != null)
// If this is not a query and we have a filename, print to a file
printToFile(outputFileName, outputFileType, inputFileName, attributes);
else
// Otherwise, print to the named printer, or to the default
// printer otherwise.
print(printerName, inputFileName, attributes);
// The main() method ends here, but there may be a printing thread
// operating in the background. So the program may not terminate
// until printing completes.
}
// List names of all PrintServices that can support the attributes
public static void queryServices(PrintRequestAttributeSet attributes) {
// Find all services that can support the specified attributes
PrintService[] services = PrintServiceLookup.lookupPrintServices(null, attributes);
// Loop through available services
for (int i = 0; i < services.length; i++) {
// Print service name
System.out.print(services[i].getName());
// Then query and print the document types it can print
DocFlavor[] flavors = services[i].getSupportedDocFlavors();
for (int j = 0; j < flavors.length; j++) {
// Filter out DocFlavors that have a representation class other
// than java.io.InputStream.
String repclass = flavors[j].getRepresentationClassName();
if (!repclass.equals("java.io.InputStream"))
continue;
System.out.println("\t" + flavors[j].getMimeType());
}
}
}
// List details about the named printer
public static void queryPrinter(String printerName, PrintRequestAttributeSet attributes) {
// Find the named printer
PrintService service = getNamedPrinter(printerName, attributes);
if (service == null) {
System.out.println(printerName + ": no such printer capable of "
+ "handling the specified attributes");
return;
}
// Print status and other information about the printer
System.out.println(printerName + " status:");
Attribute[] attrs = service.getAttributes().toArray();
for (int i = 0; i < attrs.length; i++)
System.out.println("\t" + attrs[i].getName() + ": " + attrs[i]);
}
// Print the contents of the named file to the named printer (or to a
// default printer if printerName is null) requesting the specified
// attributes.
public static void print(String printerName, String filename, PrintRequestAttributeSet attributes)
throws IOException {
// Look for a printer that can support the attributes
PrintService service = getNamedPrinter(printerName, attributes);
if (service == null) {
System.out.println("Can"t find a printer " + "with specified attributes");
return;
}
// Print the file to that printer. See method definition below
printToService(service, filename, attributes);
// Let the user know where to pick up their printout
System.out.println("Printed " + filename + " to " + service.getName());
}
// Print to an output file instead of a printer
public static void printToFile(String outputFileName, String outputFileType,
String inputFileName, PrintRequestAttributeSet attributes) throws IOException {
// Determine whether the system can print to the specified type, and
// get a factory object if so.
// The name of this static method is way too long!
StreamPrintServiceFactory[] factories = StreamPrintServiceFactory
.lookupStreamPrintServiceFactories(null, outputFileType);
// Error message if we can"t print to the specified output type
if (factories.length == 0) {
System.out.println("Unable to print files of type: " + outputFileType);
return;
}
// Open the output file
FileOutputStream out = new FileOutputStream(outputFileName);
// Get a PrintService object to print to that file
StreamPrintService service = factories[0].getPrintService(out);
// Print using the method below
printToService(service, inputFileName, attributes);
// And remember to close the output file
out.close();
}
// Print the contents of the named file to the specified PrintService,
// requesting the specified attributes.
// This is shared code used by print() and printToFile() above.
public static void printToService(PrintService service, String filename,
PrintRequestAttributeSet attributes) throws IOException {
// Figure out what type of file we"re printing
DocFlavor flavor = getFlavorFromFilename(filename);
// Open the file
InputStream in = new FileInputStream(filename);
// Create a Doc object to print from the file and flavor.
Doc doc = new SimpleDoc(in, flavor, null);
// Create a print job from the service
DocPrintJob job = service.createPrintJob();
// Monitor the print job with a listener
job.addPrintJobListener(new PrintJobAdapter() {
public void printJobCompleted(PrintJobEvent e) {
System.out.println("Print job complete");
System.exit(0);
}
public void printDataTransferCompleted(PrintJobEvent e) {
System.out.println("Document transfered to printer");
}
public void printJobRequiresAttention(PrintJobEvent e) {
System.out.println("Print job requires attention");
System.out.println("Check printer: out of paper?");
}
public void printJobFailed(PrintJobEvent e) {
System.out.println("Print job failed");
System.exit(1);
}
});
// Now print the document, catching errors
try {
job.print(doc, attributes);
} catch (PrintException e) {
System.out.println(e);
System.exit(1);
}
}
// A utility method to look up printers that can support the specified
// attributes and return the one that matches the specified name.
public static PrintService getNamedPrinter(String name, PrintRequestAttributeSet attrs) {
PrintService[] services = PrintServiceLookup.lookupPrintServices(null, attrs);
if (services.length > 0) {
if (name == null)
return services[0];
else {
for (int i = 0; i < services.length; i++) {
if (services[i].getName().equals(name))
return services[i];
}
}
}
return null;
}
// A utility method to return a DocFlavor object matching the
// extension of the filename.
public static DocFlavor getFlavorFromFilename(String filename) {
String extension = filename.substring(filename.lastIndexOf(".") + 1);
extension = extension.toLowerCase();
if (extension.equals("gif"))
return DocFlavor.INPUT_STREAM.GIF;
else if (extension.equals("jpeg"))
return DocFlavor.INPUT_STREAM.JPEG;
else if (extension.equals("jpg"))
return DocFlavor.INPUT_STREAM.JPEG;
else if (extension.equals("png"))
return DocFlavor.INPUT_STREAM.PNG;
else if (extension.equals("ps"))
return DocFlavor.INPUT_STREAM.POSTSCRIPT;
else if (extension.equals("txt"))
return DocFlavor.INPUT_STREAM.TEXT_PLAIN_HOST;
// Fallback: try to determine flavor from file content
else
return DocFlavor.INPUT_STREAM.AUTOSENSE;
}
}
Pagination during print
/*
* Copyright (c) 1995 - 2008 Sun Microsystems, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.UIManager;
public class PaginationExample implements Printable, ActionListener {
int[] pageBreaks; // array of page break line positions.
/* Synthesise some sample lines of text */
String[] textLines;
private void initTextLines() {
if (textLines == null) {
int numLines = 200;
textLines = new String[numLines];
for (int i = 0; i < numLines; i++) {
textLines[i] = "This is line number " + i;
}
}
}
public int print(Graphics g, PageFormat pf, int pageIndex)
throws PrinterException {
Font font = new Font("Serif", Font.PLAIN, 10);
FontMetrics metrics = g.getFontMetrics(font);
int lineHeight = metrics.getHeight();
if (pageBreaks == null) {
initTextLines();
int linesPerPage = (int) (pf.getImageableHeight() / lineHeight);
int numBreaks = (textLines.length - 1) / linesPerPage;
pageBreaks = new int[numBreaks];
for (int b = 0; b < numBreaks; b++) {
pageBreaks[b] = (b + 1) * linesPerPage;
}
}
if (pageIndex > pageBreaks.length) {
return NO_SUCH_PAGE;
}
/*
* User (0,0) is typically outside the imageable area, so we must translate
* by the X and Y values in the PageFormat to avoid clipping Since we are
* drawing text we
*/
Graphics2D g2d = (Graphics2D) g;
g2d.translate(pf.getImageableX(), pf.getImageableY());
/*
* Draw each line that is on this page. Increment "y" position by lineHeight
* for each line.
*/
int y = 0;
int start = (pageIndex == 0) ? 0 : pageBreaks[pageIndex - 1];
int end = (pageIndex == pageBreaks.length) ? textLines.length
: pageBreaks[pageIndex];
for (int line = start; line < end; line++) {
y += lineHeight;
g.drawString(textLines[line], 0, y);
}
/* tell the caller that this page is part of the printed document */
return PAGE_EXISTS;
}
public void actionPerformed(ActionEvent e) {
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(this);
boolean ok = job.printDialog();
if (ok) {
try {
job.print();
} catch (PrinterException ex) {
/* The job did not successfully complete */
}
}
}
public static void main(String args[]) {
try {
String cn = UIManager.getSystemLookAndFeelClassName();
UIManager.setLookAndFeel(cn); // Use the native L&F
} catch (Exception cnf) {
}
JFrame f = new JFrame("Printing Pagination Example");
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
JButton printButton = new JButton("Print Pages");
printButton.addActionListener(new PaginationExample());
f.add("Center", printButton);
f.pack();
f.setVisible(true);
}
}
Print an image out
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.swing.ImageIcon;
public class ImagePrint {
public static void main(String[] args) throws Exception {
PrintService service = PrintServiceLookup.lookupDefaultPrintService();
DocPrintJob job = service.createPrintJob();
DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
SimpleDoc doc = new SimpleDoc(new MyPrintable(), flavor, null);
job.print(doc, null);
}
}
class MyPrintable implements Printable {
ImageIcon printImage = new javax.swing.ImageIcon("a.gif");
public int print(Graphics g, PageFormat pf, int pageIndex) {
Graphics2D g2d = (Graphics2D) g;
g.translate((int) (pf.getImageableX()), (int) (pf.getImageableY()));
if (pageIndex == 0) {
double pageWidth = pf.getImageableWidth();
double pageHeight = pf.getImageableHeight();
double imageWidth = printImage.getIconWidth();
double imageHeight = printImage.getIconHeight();
double scaleX = pageWidth / imageWidth;
double scaleY = pageHeight / imageHeight;
double scaleFactor = Math.min(scaleX, scaleY);
g2d.scale(scaleFactor, scaleFactor);
g.drawImage(printImage.getImage(), 0, 0, null);
return Printable.PAGE_EXISTS;
}
return Printable.NO_SUCH_PAGE;
}
}
PrinterJob and Printable
/*
* Copyright (c) 1995 - 2008 Sun Microsystems, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.UIManager;
public class HelloWorldPrinter implements Printable, ActionListener {
public int print(Graphics g, PageFormat pf, int page) throws PrinterException {
if (page > 0) { /* We have only one page, and "page" is zero-based */
return NO_SUCH_PAGE;
}
/*
* User (0,0) is typically outside the imageable area, so we must translate
* by the X and Y values in the PageFormat to avoid clipping
*/
Graphics2D g2d = (Graphics2D) g;
g2d.translate(pf.getImageableX(), pf.getImageableY());
/* Now we perform our rendering */
g.drawString("Hello world!", 100, 100);
/* tell the caller that this page is part of the printed document */
return PAGE_EXISTS;
}
public void actionPerformed(ActionEvent e) {
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(this);
boolean ok = job.printDialog();
if (ok) {
try {
job.print();
} catch (PrinterException ex) {
/* The job did not successfully complete */
}
}
}
public static void main(String args[]) {
UIManager.put("swing.boldMetal", Boolean.FALSE);
JFrame f = new JFrame("Hello World Printer");
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
JButton printButton = new JButton("Print Hello World");
printButton.addActionListener(new HelloWorldPrinter());
f.add("Center", printButton);
f.pack();
f.setVisible(true);
}
}
Print Image
import java.io.FileInputStream;
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Copies;
public class Main {
static public void main(String args[]) throws Exception {
PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
pras.add(new Copies(1));
PrintService pss[] = PrintServiceLookup.lookupPrintServices(DocFlavor.INPUT_STREAM.GIF, pras);
PrintService ps = pss[0];
System.out.println("Printing to " + ps);
DocPrintJob job = ps.createPrintJob();
FileInputStream fin = new FileInputStream("filename.gif");
Doc doc = new SimpleDoc(fin, DocFlavor.INPUT_STREAM.GIF, null);
job.print(doc, pras);
fin.close();
}
}
Printing Pages with Different Formats
import java.awt.Graphics;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
class PrintBook {
public static void main(String[] args) {
PrinterJob pjob = PrinterJob.getPrinterJob();
Book book = new Book();
PageFormat landscape = pjob.defaultPage();
landscape.setOrientation(PageFormat.LANDSCAPE);
book.append(new Printable1(), landscape);
PageFormat portrait = pjob.defaultPage();
portrait.setOrientation(PageFormat.PORTRAIT);
book.append(new Printable2(), portrait, 5);
pjob.setPageable(book);
try {
pjob.print();
} catch (PrinterException e) {
}
}
}
class Printable1 implements Printable {
public int print(Graphics g, PageFormat pf, int pageIndex) {
drawGraphics(g, pf);
return Printable.PAGE_EXISTS;
}
public void drawGraphics(Graphics g, PageFormat pf){
}
}
class Printable2 implements Printable {
public int print(Graphics g, PageFormat pf, int pageIndex) {
drawGraphics(g, pf);
return Printable.PAGE_EXISTS;
}
public void drawGraphics(Graphics g, PageFormat pf){
}
}
Printing to a File
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Destination;
public class Main {
public static void main(String[] argv) throws Exception {
// Set up destination attribute
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
aset.add(new Destination(new java.net.URI("file:e:/temp/out.ps")));
}
}
Print out a Swing component
/*
* Copyright (c) 1995 - 2008 Sun Microsystems, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
public class PrintUIWindow implements Printable, ActionListener {
JFrame frameToPrint;
public int print(Graphics g, PageFormat pf, int page) throws PrinterException {
if (page > 0) { /* We have only one page, and "page" is zero-based */
return NO_SUCH_PAGE;
}
/*
* User (0,0) is typically outside the imageable area, so we must translate
* by the X and Y values in the PageFormat to avoid clipping
*/
Graphics2D g2d = (Graphics2D) g;
g2d.translate(pf.getImageableX(), pf.getImageableY());
/* Now print the window and its visible contents */
frameToPrint.printAll(g);
/* tell the caller that this page is part of the printed document */
return PAGE_EXISTS;
}
public void actionPerformed(ActionEvent e) {
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(this);
boolean ok = job.printDialog();
if (ok) {
try {
job.print();
} catch (PrinterException ex) {
/* The job did not successfully complete */
}
}
}
public PrintUIWindow(JFrame f) {
frameToPrint = f;
}
public static void main(String args[]) {
UIManager.put("swing.boldMetal", Boolean.FALSE);
JFrame f = new JFrame("Print UI Example");
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
JTextArea text = new JTextArea(50, 20);
for (int i = 1; i <= 50; i++) {
text.append("Line " + i + "\n");
}
JScrollPane pane = new JScrollPane(text);
pane.setPreferredSize(new Dimension(250, 200));
f.add("Center", pane);
JButton printButton = new JButton("Print This Window");
printButton.addActionListener(new PrintUIWindow(f));
f.add("South", printButton);
f.pack();
f.setVisible(true);
}
}
The area of the actual page
import java.awt.Graphics;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.swing.JComponent;
public class BasicPrint extends JComponent implements Printable {
public int print(Graphics g, PageFormat pf, int pageIndex) {
double x = 0;
double y = 0;
double w = pf.getWidth();
double h = pf.getHeight();
return Printable.NO_SUCH_PAGE;
}
public static void main(String[] args) {
PrinterJob pjob = PrinterJob.getPrinterJob();
PageFormat pf = pjob.defaultPage();
pjob.setPrintable(new BasicPrint(), pf);
try {
pjob.print();
} catch (PrinterException e) {
}
}
}
The area of the printable area
import java.awt.Graphics;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.swing.JComponent;
public class BasicPrint extends JComponent implements Printable {
public int print(Graphics g, PageFormat pf, int pageIndex) {
double ix = pf.getImageableX();
double iy = pf.getImageableY();
double iw = pf.getImageableWidth();
double ih = pf.getImageableHeight();
return Printable.NO_SUCH_PAGE;
}
public static void main(String[] args) {
PrinterJob pjob = PrinterJob.getPrinterJob();
PageFormat pf = pjob.defaultPage();
pjob.setPrintable(new BasicPrint(), pf);
try {
pjob.print();
} catch (PrinterException e) {
}
}
}
Work with PrintRequestAttributeSet
/*
* Copyright (c) 1995 - 2008 Sun Microsystems, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.swing.UIManager;
public class PrintDialogExample implements Printable {
public int print(Graphics g, PageFormat pf, int page) throws PrinterException {
if (page > 0) { /* We have only one page, and "page" is zero-based */
return NO_SUCH_PAGE;
}
/*
* User (0,0) is typically outside the imageable area, so we must translate
* by the X and Y values in the PageFormat to avoid clipping
*/
Graphics2D g2d = (Graphics2D) g;
g2d.translate(pf.getImageableX(), pf.getImageableY());
/* Now we perform our rendering */
g.drawString("Test the print dialog!", 100, 100);
/* tell the caller that this page is part of the printed document */
return PAGE_EXISTS;
}
public static void main(String args[]) {
try {
String cn = UIManager.getSystemLookAndFeelClassName();
UIManager.setLookAndFeel(cn); // Use the native L&F
} catch (Exception cnf) {
}
PrinterJob job = PrinterJob.getPrinterJob();
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
PageFormat pf = job.pageDialog(aset);
job.setPrintable(new PrintDialogExample(), pf);
boolean ok = job.printDialog(aset);
if (ok) {
try {
job.print(aset);
} catch (PrinterException ex) {
/* The job did not successfully complete */
}
}
System.exit(0);
}
}