Java 打印:创建具有最小可接受边距的 PageFormat
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10455268/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java printing: creating a PageFormat with minimum acceptable margin
提问by Jason S
I'm trying to get the PageFormat correct when I print. Below is an example program that shows my dilemma: I get a different result when I use printJob.setPrintable(printable)
than when I use printJob.setPageable(book)
when I create a Book
object using the default PageFormat from the Print job.
我试图在打印时使 PageFormat 正确。下面是一个示例程序,它显示了我的困境:当我使用打印作业中的默认 PageFormat创建对象时,我得到的结果printJob.setPrintable(printable)
与使用printJob.setPageable(book)
时得到的结果不同Book
。
When I run it, and click "Print", then "Print using Book", I see this console output:
当我运行它时,单击“打印”,然后单击“使用书籍打印”,我看到这个控制台输出:
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
What gives? The default page format when using Book
sucks and uses 1" margin on each side of the page; the "real" page format only needs about 1/6" margin on each side.
是什么赋予了?使用时的默认页面格式很Book
糟糕,在页面的每一边使用 1" 边距;“真实”页面格式只需要每边大约 1/6" 边距。
example program here:
示例程序在这里:
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);
}
}
回答by Jason S
Hmm. After trying a number of fruitless efforts, it looks like setting a page to zero margin and then calling PrinterJob.validatePage()
seems to be the only way I can get a valid minimum-margin PageFormat:
唔。在尝试了一些徒劳的努力之后,看起来像将页面设置为零边距然后调用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;
}
and then I can change doPrint()
to:
然后我可以更改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);
}
}