Reputation: 61
I want to print a very large panel and this panel contains some components like jtable, jlabel and others jpanel. Now i want to print it in differents pages. But i don't know how to do it. I have implemented Printable in my panel class. But if i print it, I get only one page.
Upvotes: 0
Views: 2648
Reputation: 852
My edit to the question from Harry was not accepted, so I post my edits as a new answer.
The following code works for me (I tested it):
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;
}
}
numPages
I changed the expression for numPages
to:
(int) Math.ceil(page.height/format.getImageableHeight())
This divides the total height (height of the jpanel) through the height of one page, thus calculating the number of all pages.
g2d.translate
I did the following change: In this line:
g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY() - pageIndex * pageFormat.getImageableHeight());
Changed componentToBePrinted.getPreferredSize().height
to pageFormat.getImageableHeight()
. A positive value for the first or the second parameter of g2d.translate
moves the graphic to the right or down respectively.
.getImageableX()
and .getImageableY()
help position the graphic so that it doesn't overlap with the padding.
For pageIndex
greater than 0
, - pageIndex * pageFormat.getImageableHeight()
moves the image pageIndex
-times the page-height to the top. So the area, that the pageIndex
refers to is printed.
original broken source:
Upvotes: 1
Reputation: 971
Try This ?
package com.mymoney.util;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.PageFormat;
import java.awt.print.Pageable;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.swing.RepaintManager;
public class PrintUtil implements Printable, Pageable {
private Component componentToBePrinted;
private PageFormat format;
private int numPages;
public PrintUtil(Component componentToBePrinted) {
this.componentToBePrinted = componentToBePrinted;
Dimension page = this.componentToBePrinted.getPreferredSize();
numPages = (int) Math.ceil(page.height/format.getImageableY());
}
public void print() {
PrinterJob printJob = PrinterJob.getPrinterJob();
printJob.setPrintable(this);
printJob.setPageable(this);
format = printJob.defaultPage();
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*componentToBePrinted.getPreferredSize().height);
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;
}
}
Reference --> https://community.oracle.com/thread/1263759?start=0&tstart=0
Upvotes: 1