Vanhelsing
Vanhelsing

Reputation: 61

How to print a large JPanel in several page

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

Answers (2)

aiutopia.dev
aiutopia.dev

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:

https://community.oracle.com

Upvotes: 1

Harry
Harry

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

Related Questions