Sending JPanel to Printer
3 answers
Check out the Java Print API and tutorial along with JComponent.print (Graphics).
Here is a rudimentary class that will print any component that fits on 1 page (I can't take credit for this, I got the code from Marty Hall ):
import java.awt.*;
import java.awt.print.*;
import javax.swing.*;
/**
* Generic component printer. This object allows any AWT or Swing component (or DCT system)
* to be printed by performing it pre and post print responsibilities.
* <p>
* When printing components, the role of the print method is nothing more than to scale the Graphics, turn off double
* buffering, and call paint. There is no particular reason to put that print method in the component being printed. A
* better approach is to build a generic printComponent method to which you simply pass the component you want printed.
* <p>
* With Swing, almost all components have double buffering turned on by default. In general, this is a great benefit,
* making for convenient and efficient painting. However, in the specific case of printing, it can is a huge problem.
* First, since printing components relies on scaling the coordinate system and then simply calling the component's
* paint method, if double buffering is enabled printing amounts to little more than scaling up the buffer (off-screen
* image) which results in ugly low-resolution printing like you already had available. Secondly, sending these huge
* buffers to the printer results in huge print spooler files which take a very long time to print. Consequently this
* object globally turns off double buffering before printing and turns it back on afterwards.
* <p>
* Threading Design : [x] Single Threaded [ ] Threadsafe [ ] Immutable [ ] Isolated
*/
public class ComponentPrinter
extends Object
implements Printable
{
// *****************************************************************************
// INSTANCE PROPERTIES
// *****************************************************************************
private Component component; // the component to print
// *****************************************************************************
// INSTANCE CREATE/DELETE
// *****************************************************************************
public ComponentPrinter(Component com) {
component=com;
}
// *****************************************************************************
// INSTANCE METHODS
// *****************************************************************************
public void print() throws PrinterException {
PrinterJob printJob=PrinterJob.getPrinterJob();
printJob.setPrintable(this);
if(printJob.printDialog()) {
printJob.print();
}
}
public int print(Graphics gc, PageFormat pageFormat, int pageIndex) {
if(pageIndex>0) {
return NO_SUCH_PAGE;
}
RepaintManager mgr=RepaintManager.currentManager(component);
Graphics2D g2d=(Graphics2D)gc;
g2d.translate(pageFormat.getImageableX(),pageFormat.getImageableY());
mgr.setDoubleBufferingEnabled(false); // only for swing components
component.paint(g2d);
mgr.setDoubleBufferingEnabled(true); // only for swing components
return PAGE_EXISTS;
}
// *****************************************************************************
// STATIC METHODS
// *****************************************************************************
static public void printComponent(Component com) throws PrinterException {
new ComponentPrinter(com).print();
}
} // END PUBLIC CLASS
+4
source to share
consider this answer for printing Component
multiple pages:
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.*;
import javax.swing.RepaintManager;
public class PrintMultiPageUtil implements Printable, Pageable {
private Component componentToBePrinted;
private PageFormat format;
private int numPages;
public PrintMultiPageUtil(Component componentToBePrinted) {
this.componentToBePrinted = componentToBePrinted;
// get total space from component
Dimension totalSpace = this.componentToBePrinted.getPreferredSize();
// calculate for DIN A4
format = PrinterJob.getPrinterJob().defaultPage();
numPages = (int) Math.ceil(totalSpace .height/format.getImageableHeight());
}
public void print() {
PrinterJob printJob = PrinterJob.getPrinterJob();
// show page-dialog with default DIN A4
format = printJob.pageDialog(printJob.defaultPage());
printJob.setPrintable(this);
printJob.setPageable(this);
if (printJob.printDialog())
try {
printJob.print();
} catch(PrinterException pe) {
System.out.println("Error printing: " + pe);
}
}
public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
if ((pageIndex < 0) | (pageIndex >= numPages)) {
return(NO_SUCH_PAGE);
} else {
Graphics2D g2d = (Graphics2D)g;
g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY() - pageIndex * pageFormat.getImageableHeight());
disableDoubleBuffering(componentToBePrinted);
componentToBePrinted.paint(g2d);
enableDoubleBuffering(componentToBePrinted);
return(PAGE_EXISTS);
}
}
public static void disableDoubleBuffering(Component c) {
RepaintManager currentManager = RepaintManager.currentManager(c);
currentManager.setDoubleBufferingEnabled(false);
}
public static void enableDoubleBuffering(Component c) {
RepaintManager currentManager = RepaintManager.currentManager(c);
currentManager.setDoubleBufferingEnabled(true);
}
@Override
public int getNumberOfPages() {
// TODO Auto-generated method stub
return numPages;
}
@Override
public PageFormat getPageFormat(int arg0) throws IndexOutOfBoundsException {
return format;
}
@Override
public Printable getPrintable(int arg0) throws IndexOutOfBoundsException {
// TODO Auto-generated method stub
return this;
}
}
0
source to share