当前位置: 首页 > 面试题库 >

Java打印:创建具有最小可接受边距的PageFormat

卞经业
2023-03-14
问题内容

我正在尝试打印时正确设置PageFormat。下面是显示我的困境的示例程序:printJob.setPrintable(printable)使用printJob.setPageable(book)时和Book使用打印作业中的默认PageFormat
创建对象时使用的结果不同。

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

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);
    }
}


 类似资料:
  • 问题内容: 我正在使用单独的样式表进行打印。是否可以在设置打印页边距的样式表中设置左右页边距(即纸张上的页边距)。 谢谢。 问题答案: 指定打印时,应使用或作为单位。使用像素会导致浏览器将其转换为类似于屏幕上的外观。使用或将确保纸张尺​​寸一致。 对于字体大小,用于打印介质。 请注意,以css样式设置主体上的页边距 不会 调整定义打印机可打印区域的打印机驱动程序中的页边距,或由浏览器控制的页边距(

  • 问题内容: 我尝试将大小设置为零或在Java中删除打印文档的边框。它始终具有标准的白色边框。 这是我打印JPanel和一些组件的功能: 我正在使用Adobe PDF打印机,因为这里没有任何打印机。有什么建议? 问题答案: 使用带有参数的PrinterJob.setPrintable()版本。 在PageFormat中,设置纸张的可成像区域没有边框(x = 0,y = 0,width =纸张的宽度,

  • 我刚刚开始在HackerRank上练习,以提高我的编码技巧。我主要使用Java作为我的首选语言。我已经得到了这个问题,我已经尽力给出了解决方案,但没有清除所有的测试用例。我已经清除了15个测试用例中的5个,但仍有10个需要完成。那些在hackerrank上的人可以通过以下链接看到这个问题:最小-最大和 无论如何,我给出了这个问题的简要描述: 问题陈述 给定五个正整数,通过将五个整数中的恰好四个求和

  • 我试图从代码厨师那里解决识别素数的问题 爱丽丝和鲍勃过了很长时间才见面。像往常一样,他们喜欢玩一些数学游戏。这一次爱丽丝接了电话,决定了比赛。游戏很简单,爱丽丝说出一个整数,鲍勃必须说出这个数字是否是质数。鲍勃像往常一样知道逻辑,但由于爱丽丝没有给鲍勃太多时间思考,所以鲍勃决定写一个计算机程序。 通过编写一个计算机程序来帮助Bob完成这项任务,该程序将计算该数字是否为素数。 输入 输入的第一行包含

  • 问题内容: 我是Java的初学者,也是我的一项工作。我必须做数据库操作。我有用于将数据插入数据库的Java代码,它工作正常。 我的问题是,每次代码运行时,我的代码都必须创建一个数据库连接和准备好的语句对象,据我所知,这是一项昂贵的操作。 有什么方法可以保持与数据库的单个连接并使用该连接来执行数据库工作? 问题答案: 您可以像这样使用设计模式Singleton Connection: 1-创建一个类

  • 本文向大家介绍javaScript 连接打印机,打印小票的实例,包括了javaScript 连接打印机,打印小票的实例的使用技巧和注意事项,需要的朋友参考一下 如下所示: 以上这篇javaScript 连接打印机,打印小票的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持呐喊教程。