2010-05-19 29 views
1

我正在嘗試打印可打印組件(發票文檔)。我使用JComponent而不是JPanel,因爲我不想要背景。該組件有許多子組件。我的可打印Swing組件的所有部分都不打印

主要組件實現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

你也許可以遍歷Component[]通過getComponents()返回,但一個簡單的權宜之計,如下圖所示。請注意屏幕預覽和打印輸出之間的區別。此外,請注意使用validate()而不是doLayout()。最後,爲了方便預覽,這個例子實現了Using Print Setup Dialogs

附錄:您也可以查看Printing Support in Swing Components並比較在此example中採取的方法。

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(); 
      } 
     } 
    } 
} 
+0

謝謝,但我不明白我可以如何使用I.e.在我的例子中,如果我使用JTextField而不是JLabel,則使用'javax.swing.text.JTextComponent.print()'。當我執行'printAll(g)'時,不是調用'print()'方法嗎?或者我必須爲此編寫任何特定的代碼? – Jonas 2010-05-20 15:52:16

+0

這取決於您是要打印屏幕上顯示的內容還是「JTextComponent」中可能太大而無法滾動的內容。 – trashgod 2010-05-20 17:38:10