2012-05-04 15 views
8

Próbuję uzyskać poprawność PageFormat podczas drukowania. Poniżej znajduje się przykładowy program, który pokazuje mój dylemat: otrzymuję inny wynik, gdy używam printJob.setPrintable(printable), niż gdy używam printJob.setPageable(book) podczas tworzenia obiektu Book przy użyciu domyślnego PageFormat z zadania drukowania.Drukowanie w języku Java: tworzenie PageFormat z minimalnym dopuszczalnym marginesem

Kiedy go uruchomić, a następnie kliknij przycisk „Drukuj”, a następnie „Drukuj za pomocą książki”, widzę to wyjście konsoli:

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 

Co daje? Domyślny format strony przy korzystaniu z Book zasysa i wykorzystuje 1 "margines z każdej strony strony, a" prawdziwy "format strony wymaga jedynie marginesu 1/6" na każdej stronie.

przykładowy program tutaj:

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); 
    } 
} 

Odpowiedz

17

Hmm. Po wypróbowaniu kilku bezowocnych wysiłków, wygląda na to ustawienie stronę do marży zerowej, a następnie wywołanie PrinterJob.validatePage() wydaje się być jedynym sposobem mogę uzyskać poprawny PageFormat minimalnej margin:

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;  
} 

i wtedy mogę zmienić doPrint() na:

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); 
    } 
} 
Powiązane problemy