我打算在打印时尝试使PageFormat正确。下面是一个显示我的困境的示例程序:当我使用printJob.setPrintable(printable)
时,当我使用来自Print作业的默认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);
}
}
答案 0 :(得分:17)
嗯。在尝试了一些毫无结果的努力之后,看起来将页面设置为零边距然后调用PrinterJob.validatePage()
似乎是我获得有效最小边距页面格式的唯一方法:
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);
}
}