How to print a large JPanel in several page

空扰寡人 提交于 2019-11-28 02:26:29

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

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!