我的Printable Swing组件的所有部分都不会打印

时间:2010-05-19 11:26:33

标签: java swing printing jcomponent

我正在尝试打印一个可打印的组件(发票文档)。我使用JComponent代替JPanel,因为我不想要背景。该组件有许多子组件。

主要组件实现了Printable,并且有一个print - 方法调用printAll(g),以便打印所有子组件。但我的子组件不打印。

我错过了什么?是否所有子组件都必须实现Printable?

在我的代码中, TopHeader 不会被打印。

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class PPanel extends JComponent implements Printable {
    static double w;
    static double h;

    public PPanel() {
        this.setLayout(new BorderLayout());

        this.add(new JLabel("Document Body"), BorderLayout.CENTER);
        this.add(new TopHeader(), BorderLayout.NORTH);
    }

    class TopHeader extends JComponent {
        public TopHeader() {
            this.setLayout(new BorderLayout());
            JLabel companyName = new JLabel("Company name");
            JLabel docType = new JLabel("Document type");
            this.add(companyName, BorderLayout.WEST);
            this.add(docType, BorderLayout.EAST);
        }
    }

    public static void main(String[] args) {
        final PPanel p = new PPanel();
        PrinterJob job = PrinterJob.getPrinterJob();
        job.setPrintable(p);
        try {
            job.print();
        } catch (PrinterException ex) {
            // print failed
        }
            // Preview
        new JFrame() {{ getContentPane().add(p); this.setSize((int)w, (int)h); setVisible(true); }};

    }

    @Override
    public int print(Graphics g, PageFormat pf, int page)
            throws PrinterException {
        if (page > 0) {
            return NO_SUCH_PAGE;
        }

        Graphics2D g2d = (Graphics2D)g;
        g2d.translate(pf.getImageableX(), pf.getImageableY());

        w = pf.getImageableWidth();
        h = pf.getHeight();

        this.setSize((int)w, (int)h);
        this.setPreferredSize(new Dimension((int)w, (int)h));
        this.doLayout();

        this.printAll(g);
        return PAGE_EXISTS;
    }
}

1 个答案:

答案 0 :(得分:1)

您可能会遍历Component[]返回的getComponents(),但下面会显示一个简单的权宜之计。请注意屏幕预览和打印输出之间的区别。另请注意validate()优先于doLayout()使用import java.awt.*; import java.awt.print.*; import javax.swing.*; public class PPanel extends JComponent implements Printable { private JComponent top = new TopHeader(); private JComponent mid = new JLabel("Document Body"); public PPanel() { this.setLayout(new BorderLayout()); this.add(top, BorderLayout.NORTH); this.add(mid, BorderLayout.CENTER); } private static class TopHeader extends JComponent { public TopHeader() { this.setLayout(new BorderLayout()); JLabel companyName = new JLabel("Company name"); JLabel docType = new JLabel("Document type"); this.add(companyName, BorderLayout.WEST); this.add(docType, BorderLayout.EAST); } } @Override public int print(Graphics g, PageFormat pf, int page) throws PrinterException { if (page > 0) { return NO_SUCH_PAGE; } Graphics2D g2d = (Graphics2D)g; g2d.translate(pf.getImageableX(), pf.getImageableY()); int w = (int)pf.getImageableWidth(); int h = (int)pf.getImageableHeight(); top.setSize(new Dimension(w, top.getPreferredSize().height)); this.setSize(w, h); this.validate(); this.printAll(g2d); return PAGE_EXISTS; } public static void main(String[] args) { final PPanel p = new PPanel(); // Preview before print() new JFrame() { { this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.add(p); this.pack(); this.setVisible(true); } }; PrinterJob pj = PrinterJob.getPrinterJob(); PageFormat pf = pj.pageDialog(pj.defaultPage()); pj.setPrintable(p, pf); if (pj.printDialog()) { try { pj.print(); } catch (PrinterException pe) { pe.printStackTrace(); } } } } 。最后,为了便于预览,此示例实现了Using Print Setup Dialogs

附录:您也可以查看Printing Support in Swing Components并比较此example中采用的方法。

{{1}}