【问题标题】:Java printing: creating a PageFormat with minimum acceptable marginJava 打印:创建具有最小可接受边距的 PageFormat
【发布时间】:2012-05-04 19:52:28
【问题描述】:

我正在尝试在打印时使 PageFormat 正确。下面是一个示例程序,显示了我的困境:使用 printJob.setPrintable(printable) 时得到的结果与使用打印作业中的默认 PageFormat 创建 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);
    }
}

【问题讨论】:

    标签: java printing


    【解决方案1】:

    嗯。在尝试了许多徒劳无功的努力之后,看起来将页面设置为零边距然后调用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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-31
      • 2012-03-29
      • 1970-01-01
      • 2011-12-19
      • 1970-01-01
      相关资源
      最近更新 更多