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.
-
Have you considered taking all the individual components and putting them on their own JPanels specifically for printing? – Compass Sep 18 '14 at 17:42
-
Yes i tried to make a list of JPanel and print them with Book object. In the dialog it show 6 page but i get one page after printing. Also if i do it get i get all pages of JTable which are large? – Vanhelsing Sep 18 '14 at 17:51
-
What you can try doing is having them print to a PDF using iText. That will save paper and allow you to see your results and modify them quickly. – Compass Sep 18 '14 at 17:54
-
I use PDF creator to preview the result. I don't know how to use iText. For JTable i don't need to implement Printable or Pageable. So if i print it will i get all pages if it is large? If yes, i will retry to print them individually – Vanhelsing Sep 18 '14 at 18:05
-
There is a way to convert a JPanel to a printable object and pass it over to iText as an entire page. I believe it was a Graphics2D but I don't have the source or memory of what it was. You could technically get individual components and slice them off into each page based on the actual size of the JPanel (i.e. print (0,0,600,600) then (0,600,0,1200)). If you're just trying to print the JPanel as it appears, as opposed to everything on the JTable. – Compass Sep 18 '14 at 18:07
-
I think you are right. I will try to do what you say. Thank you – Vanhelsing Sep 18 '14 at 18:13
-
@Compass do you mean [this](https://stackoverflow.com/a/750462/1273555)? Can you post a complete example as an answer, please? – ArchLinuxTux Mar 19 '18 at 11:02
2 Answers
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

- 951
- 2
- 12
- 18
-
1
-
-
I'm going to print all JPanel individually. I think that it is the best way – Vanhelsing Sep 19 '14 at 12:54
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:

- 840
- 1
- 11
- 28