2010-05-19 4 views
1

인쇄 가능한 구성 요소 (송장 문서)를 인쇄하려고합니다. 배경을 원하지 않기 때문에 JPanel 대신 JComponent을 사용합니다. 구성 요소에는 많은 하위 구성 요소가 있습니다.인쇄용 스윙 구성 요소의 모든 부분이 인쇄되지 않습니다.

주 구성 요소는 인쇄 가능을 구현하고 printAll(g)을 호출하는 print 메서드를 사용하므로 모든 하위 구성 요소를 인쇄해야합니다. 그러나 내 하위 구성 요소는 인쇄되지 않습니다.

무엇이 누락 되었습니까? 모든 하위 구성 요소도 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()에 의해 반환 할 수 있지만 간단한 편법은 다음과 같습니다. 화면 미리보기와 인쇄물의 차이점에 유의하십시오. 또한 doLayout()보다 validate()을 우선 사용하십시오. 마지막으로 미리보기의 편의를 위해이 예제에서는 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

감사합니다. 그러나 어떻게 사용할 수 있는지 이해할 수 없습니다. 내 JLabel의 JTextField istead를 사용하는 경우 내 예제에서'javax.swing.text.JTextComponent.print()'. 'printAll (g)'할 때'print()'메소드가 호출되지 않습니까? 아니면 이에 대한 특정 코드를 작성해야합니까? – Jonas

+0

그것은 화면에 무엇이 인쇄되는지 또는 스크롤없이 적합하기에는 너무 큰 "JTextComponent"에있는 것을 인쇄 할 것인지에 달려 있습니다. – trashgod

관련 문제