打印JFrame及其组件

我一直在做一个大的程序,它的一个function应该是打印主窗口的内容。 我检查了API,发现这个例子:

http://docs.oracle.com/javase/tutorial/2d/printing/gui.html

这是非常有帮助的,我试图在我的程序中使用该代码,将其置于我的打印button的actionperformed方法中:

PrinterJob job = PrinterJob.getPrinterJob(); job.setPrintable(this); boolean ok = job.printDialog(); if (ok) { try { job.print(); } catch (PrinterException ex) { /* The job did not successfully complete */ } } 

如果我点击打印button,我得到一个打印机对话框,当我告诉它打印,它只是打印一个空白的文件。 我知道上面的代码并不是我所需要的,正如我在API的例子中看到的那样,有一个print()方法,但显然他们从来没有调用它,所以它很混乱。 我尝试过多次使用它,但没有成功。

另外,我认为当我最终打印时,我的窗口需要以横向打印,甚至可能需要一些缩放。 任何想法如何做到这一点?

我想任何有用的帮助,以帮助我成功地实现这个代码。 我知道我应该可以通过检查文档(我已经尝试了将近2天)来完成,但是我无法完成它。 我通过互联网了解了我所知道的所有编程。 任何帮助将不胜感激。

这是一个简单的解决scheme。 我有一个Printer类实现打印,它将处理打印作业:

 public static class Printer implements Printable { final Component comp; public Printer(Component comp){ this.comp = comp; } @Override public int print(Graphics g, PageFormat format, int page_index) throws PrinterException { if (page_index > 0) { return Printable.NO_SUCH_PAGE; } // get the bounds of the component Dimension dim = comp.getSize(); double cHeight = dim.getHeight(); double cWidth = dim.getWidth(); // get the bounds of the printable area double pHeight = format.getImageableHeight(); double pWidth = format.getImageableWidth(); double pXStart = format.getImageableX(); double pYStart = format.getImageableY(); double xRatio = pWidth / cWidth; double yRatio = pHeight / cHeight; Graphics2D g2 = (Graphics2D) g; g2.translate(pXStart, pYStart); g2.scale(xRatio, yRatio); comp.paint(g2); return Printable.PAGE_EXISTS; } } 

接下来,打印它:

 JFrame yourComponent = new JFrame(); PrinterJob pjob = PrinterJob.getPrinterJob(); PageFormat preformat = pjob.defaultPage(); preformat.setOrientation(PageFormat.LANDSCAPE); PageFormat postformat = pjob.pageDialog(preformat); //If user does not hit cancel then print. if (preformat != postformat) { //Set print component pjob.setPrintable(new Printer(yourComponent), postformat); if (pjob.printDialog()) { pjob.print(); } } 

这是我的想法的转折…

打印以适合…

A4-飞度

打印填写…

A4-填充

 public class TestPrinting { public static void main(String[] args) { try { printComponentToFile(new PrintForm(), true); printComponentToFile(new PrintForm(), false); } catch (PrinterException exp) { exp.printStackTrace(); } } public static void printComponent(JComponent comp, boolean fill) throws PrinterException { PrinterJob pjob = PrinterJob.getPrinterJob(); PageFormat pf = pjob.defaultPage(); pf.setOrientation(PageFormat.LANDSCAPE); PageFormat postformat = pjob.pageDialog(pf); if (pf != postformat) { //Set print component pjob.setPrintable(new ComponentPrinter(comp, fill), postformat); if (pjob.printDialog()) { pjob.print(); } } } public static void printComponentToFile(Component comp, boolean fill) throws PrinterException { Paper paper = new Paper(); paper.setSize(8.3 * 72, 11.7 * 72); paper.setImageableArea(18, 18, 559, 783); PageFormat pf = new PageFormat(); pf.setPaper(paper); pf.setOrientation(PageFormat.LANDSCAPE); BufferedImage img = new BufferedImage( (int) Math.round(pf.getWidth()), (int) Math.round(pf.getHeight()), BufferedImage.TYPE_INT_RGB); Graphics2D g2d = img.createGraphics(); g2d.setColor(Color.WHITE); g2d.fill(new Rectangle(0, 0, img.getWidth(), img.getHeight())); ComponentPrinter cp = new ComponentPrinter(comp, fill); try { cp.print(g2d, pf, 0); } finally { g2d.dispose(); } try { ImageIO.write(img, "png", new File("Page-" + (fill ? "Filled" : "") + ".png")); } catch (IOException ex) { ex.printStackTrace(); } } public static class ComponentPrinter implements Printable { private Component comp; private boolean fill; public ComponentPrinter(Component comp, boolean fill) { this.comp = comp; this.fill = fill; } @Override public int print(Graphics g, PageFormat format, int page_index) throws PrinterException { if (page_index > 0) { return Printable.NO_SUCH_PAGE; } Graphics2D g2 = (Graphics2D) g; g2.translate(format.getImageableX(), format.getImageableY()); double width = (int) Math.floor(format.getImageableWidth()); double height = (int) Math.floor(format.getImageableHeight()); if (!fill) { width = Math.min(width, comp.getPreferredSize().width); height = Math.min(height, comp.getPreferredSize().height); } comp.setBounds(0, 0, (int) Math.floor(width), (int) Math.floor(height)); if (comp.getParent() == null) { comp.addNotify(); } comp.validate(); comp.doLayout(); comp.printAll(g2); if (comp.getParent() != null) { comp.removeNotify(); } return Printable.PAGE_EXISTS; } } } 

一些更广泛的问题…

  • 您或多或less地对打印的组件的布局负责。 至less你会想确定它们是否合适,或者你有什么样的溢出机制。
  • 您可能需要“欺骗”尚未显示在屏幕上的组件,以为它们是……因此,所有使用addNotify / validate / doLayout都很doLayout 。 即使在屏幕上显示,如果您修改了界限,您可能需要调用这些方法。