打印多页JPanel

时间:2015-10-01 10:31:51

标签: java printing

我很担心这个问题,因为我害怕我会被告知。我正在尝试打印一个大约4页长的JPanel。它可能更多,数据来自JDBC MySql查询,最终可能会更多4.我试图打印的JPanel充满了其他JPanels(竞争对手的竞争细节),我通过ListArray ..

无论如何,我整天都在通过stackoverflow搜索,并找到了我试图实现的代码示例。可打印的类只打印第一页,所以我试图实现可分页的类,但我似乎无法做到正确。我试图实现Book课程,但不知道如何将我的JPanel添加到书中。我看过herehere等等(我只允许发布2个链接)。 这是我目前的代码(我得到了@madprogrammer给出的答案之一) -

int printButton = JOptionPane.showOptionDialog(null, scrollPane, "Race Winners", JOptionPane.YES_NO_OPTION,
        JOptionPane.PLAIN_MESSAGE, // no Icon
        null, //do not use a custom Icon
        options, //the titles of buttons
        options[0]); //default button title

if (printButton == 0) {
    try {
        printComponent(pane, true);

        //printComponentToFile(pane, false);

    } catch (PrinterException exp) {
        exp.printStackTrace();
    }

    public static void printComponent(JComponent comp, boolean fill) throws PrinterException {
        PrinterJob pjob = PrinterJob.getPrinterJob();
        //pjob.setPageable(comp);
        PageFormat pf = pjob.defaultPage();
        pf.setOrientation(PageFormat.PORTRAIT);

        PageFormat postformat = pjob.pageDialog(pf);

        if (pf != postformat) {
            //Set print component
            //pjob.setPageable(comp);
            pjob.setPrintable(new ComponentPrinter(comp, fill), postformat);

            if (pjob.printDialog()) {
                pjob.print();
            }
        }
    }

    public static void printComponentToFile(Component comp, boolean fill) throws PrinterException {
        Paper paper = new Paper();
        paper.setSize(8.3 * 72, 11.7 * 72);
        paper.setImageableArea(18, 18, 559, 783);

        PageFormat pf = new PageFormat();
        pf.setPaper(paper);
        pf.setOrientation(PageFormat.PORTRAIT);

        BufferedImage img = new BufferedImage(
        (int) Math.round(pf.getWidth()), (int) Math.round(pf.getHeight()),
        BufferedImage.TYPE_INT_RGB);

        Graphics2D g2d = img.createGraphics();
        g2d.setColor(Color.WHITE);
        g2d.fill(new Rectangle(0, 0, img.getWidth(), img.getHeight()));
        ComponentPrinter cp = new ComponentPrinter(comp, fill);

        try {
            cp.print(g2d, pf, 0);
        } finally {
            g2d.dispose();
        }

        try {
            ImageIO.write(img, "png", new File("Page-" + (fill ? "Filled" : "") + ".png"));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public static class ComponentPrinter implements Printable, Pageable {
        private Component comp;
        private boolean fill;
        int numPages;
        PageFormat format;


        public ComponentPrinter(Component comp, boolean fill) {
            this.comp = comp;
            this.fill = fill;
        }

        @Override
        public int print(Graphics g, PageFormat format, int page_index) throws PrinterException {

            numPages = (int) Math.ceil(comp.getHeight() / format.getImageableY());
            System.out.print(numPages);

            if (page_index > 0) {
                return Printable.NO_SUCH_PAGE;
            }

            Graphics2D g2 = (Graphics2D) g;
            g2.translate(format.getImageableX(), format.getImageableY());
            //g2.translate(format.getImageableX(), format.getImageableY()- page_index*comp.getPreferredSize().height);

            double width = (int) Math.floor(format.getImageableWidth());
            double height = (int) Math.floor(format.getImageableHeight());

            if (!fill) {

                width = Math.min(width, comp.getPreferredSize().width);
                height = Math.min(height, comp.getPreferredSize().height);

            }

            comp.setBounds(0, 0, (int) Math.floor(width), (int) Math.floor(height));
            if (comp.getParent() == null) {
                comp.addNotify();
            }
            comp.validate();
            comp.doLayout();
            comp.printAll(g2);
            if (comp.getParent() != null) {
                comp.removeNotify();
            }

            return Printable.PAGE_EXISTS;
        }
        @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;
        }
}

这一切都有效,但只打印第一页。我真的很感激在这个方向上轻推一下,因为我很难过。 TIA: - )

1 个答案:

答案 0 :(得分:0)

这是您在多个页面上打印ComponentJPanel)的方式:

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

我将numPages的表达式更改为:

(int) Math.ceil(page.height/format.getImageableHeight())

这将总高度(jpanel的高度)除以一页的高度,从而计算所有页面的数量。

<强> g2d.translate

我做了以下更改:在这一行:

g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY() - pageIndex * pageFormat.getImageableHeight());

componentToBePrinted.getPreferredSize().height更改为pageFormat.getImageableHeight()g2d.translate的第一个或第二个参数的正值分别将图形向右或向下移动。

.getImageableX().getImageableY()有助于定位图形,使其与填充不重叠。

对于大于pageIndex的{​​{1}},0会将图片- pageIndex * pageFormat.getImageableHeight() - 将页面高度移动到顶部。因此打印pageIndex所指的区域。

原始破解来源:https://community.oracle.com

这是我的original answer