我在打印时试图使PageFormat正确。下面是显示我的难题的示例程序:当我使用printJob.setPrintable(printable)时,与使用Printt作业中的默认PageFormat创建printJob.setPageable(book)对象时,使用Book时得到的结果不同。

当我运行它时,单击“打印”,然后单击“使用书本打印”,我看到以下控制台输出:

doPrint(false)
printing on 612.000000x792.000000 paper, imageable area=588.960000x768.960000
printing on 612.000000x792.000000 paper, imageable area=588.960000x768.960000
printing on 612.000000x792.000000 paper, imageable area=588.960000x768.960000
doPrint(true)
printing on 612.000000x792.000000 paper, imageable area=468.000000x648.000000
printing on 612.000000x792.000000 paper, imageable area=468.000000x648.000000

是什么赋予了?使用Book时的默认页面格式很烂,并且在页面的每侧使用1“边距;“实际”页面格式在每一侧仅需要大约1/6”的边距。

示例程序在这里:
package com.example.printing;

import java.awt.BasicStroke;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.geom.Rectangle2D;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;

import javax.swing.AbstractAction;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class PrintRectangles extends JFrame
{
    static final int Nrectangles = 3;

    static class RectangleThingy extends JPanel implements Printable
    {
        @Override public int print(Graphics graphics,
                PageFormat pageFormat,
                int pageIndex)
            throws PrinterException
        {
            describePageFormat(pageFormat);
            if (pageIndex > 0) {
                return(NO_SUCH_PAGE);
            }
            else {
                Graphics2D g2d = (Graphics2D)graphics;
                g2d.translate(pageFormat.getImageableX(),
                        pageFormat.getImageableY());
                double w = pageFormat.getImageableWidth();
                double h = pageFormat.getImageableHeight();
                final int N = (Nrectangles - 1) / 2;
                final double spacing = 7.2; // 1/10 inch
                g2d.setStroke(new BasicStroke(0.1f));
                for (int i = -N; i <= N; ++i)
                {
                    double dx = i*spacing;
                    Rectangle2D r = new Rectangle2D.Double(
                            dx, dx, w-2*dx, h-2*dx
                            );
                    g2d.draw(r);
                }
                Rectangle2D rthick = new Rectangle2D.Double(
                        0, 0, w, h
                        );
                g2d.setStroke(new BasicStroke(1.0f));
                g2d.draw(rthick);
                return(PAGE_EXISTS);
            }
        }

        private void describePageFormat(PageFormat pageFormat) {
            System.out.println(String.format("printing on %fx%f paper, imageable area=%fx%f",
                    pageFormat.getWidth(),
                    pageFormat.getHeight(),
                    pageFormat.getImageableWidth(),
                    pageFormat.getImageableHeight()
                    ));

        }
    }

    static private class PrintPreviewPanel extends JPanel
    {
        final private Printable p;
        final private PageFormat pageFormat;
        public PrintPreviewPanel(Printable p, PageFormat pf)
        {
            this.p = p;
            this.pageFormat = pf;
        }
        @Override public Dimension getPreferredSize() {
            return new Dimension((int)this.pageFormat.getWidth(),
                    (int)this.pageFormat.getHeight());
        }
        @Override protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            try {
                p.print(g, this.pageFormat, 0);
            } catch (PrinterException e) {
                e.printStackTrace();
            }
        }
    }

    public PrintRectangles(String title) {
        super(title);
        JPanel panel = new JPanel();
        setContentPane(panel);
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
        JButton printButton = new JButton("Print");
        JButton printUsingBookButton = new JButton("Print using Book");
        JButton printPreviewButton = new JButton("Print preview");
        panel.add(printButton);
        panel.add(printUsingBookButton);
        panel.add(printPreviewButton);
        printButton.addActionListener(new AbstractAction("print") {
            @Override public void actionPerformed(ActionEvent e) {
                doPrint(false);
            }
        });
        printUsingBookButton.addActionListener(new AbstractAction("printUsingBook") {
            @Override public void actionPerformed(ActionEvent e) {
                doPrint(true);
            }
        });
        printPreviewButton.addActionListener(new AbstractAction("printPreview") {
            @Override public void actionPerformed(ActionEvent e) {
                doPrintPreview();
            }
        });
    }

    protected void doPrint(boolean useBook) {
        RectangleThingy rectangleThingy = new RectangleThingy();
        System.out.println("doPrint("+useBook+")");
        try
        {
            PrinterJob printJob = PrinterJob.getPrinterJob();
            PageFormat pageFormat = printJob.getPageFormat(null);
            if (useBook)
            {
                Book book = new Book();
                book.append(rectangleThingy, pageFormat);
                printJob.setPageable(book);
            }
            else
            {
                printJob.setPrintable(rectangleThingy);
            }
            if (printJob.printDialog())
                printJob.print();
        }
        catch(PrinterException pe) {
            System.out.println("Error printing: " + pe);
        }
    }

    protected void doPrintPreview() {
        RectangleThingy rt = new RectangleThingy();
        JFrame frame = new JFrame("print preview");

        // hack for now -- how do we get this from the printer?
        Paper paper = new Paper();
        double dotsperinch = 72;
        double margin = 0.125*dotsperinch;
        double w = 8.5*dotsperinch;
        double h = 11*dotsperinch;
        paper.setImageableArea(margin, margin, w-2*margin, h-2*margin);
        paper.setSize(w, h);
        PageFormat pfmt = new PageFormat();
        pfmt.setPaper(paper);
        frame.setContentPane(new PrintPreviewPanel(rt, pfmt));
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        new PrintRectangles("PrintRectangles").start();
    }

    private void start() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        pack();
        setVisible(true);
    }
}

最佳答案

唔。尝试了无济于事的努力之后,似乎将页面设置为零页边距,然后调用 PrinterJob.validatePage() 似乎是我可以获得有效的最小边距PageFormat的唯一方法:

static private PageFormat getMinimumMarginPageFormat(PrinterJob printJob) {
    PageFormat pf0 = printJob.defaultPage();
    PageFormat pf1 = (PageFormat) pf0.clone();
    Paper p = pf0.getPaper();
    p.setImageableArea(0, 0,pf0.getWidth(), pf0.getHeight());
    pf1.setPaper(p);
    PageFormat pf2 = printJob.validatePage(pf1);
    return pf2;
}

然后我可以将doPrint()更改为:
protected void doPrint(boolean useBook) {
    RectangleThingy rectangleThingy = new RectangleThingy();
    System.out.println("doPrint("+useBook+")");
    try
    {
        PrinterJob printJob = PrinterJob.getPrinterJob();
        if (useBook)
        {
            Book book = new Book();
            book.append(rectangleThingy, getMinimumMarginPageFormat(printJob));
            printJob.setPageable(book);
        }
        else
        {
            printJob.setPrintable(rectangleThingy);
        }
        if (printJob.printDialog())
            printJob.print();
    }
    catch(PrinterException pe) {
        System.out.println("Error printing: " + pe);
    }
}

关于Java打印: creating a PageFormat with minimum acceptable margin,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10455268/

10-12 03:05