2013-01-22 64 views
2

有没有一种方法可以在Java中绑定PrinterJob以实际不打印到打印机,以便我可以获取每个页面的图形对象?我试着将PrintService设置为null,但Java不允许这样做。使用PrinterJob打印图像(Graphics2D)

这样我就可以为文档检索准确的打印预览,而不必在不同的上下文中从头开始重建PrinterJobs函数。

下面是我在程序的打印功能的代码:

public int print(Graphics graphics, PageFormat pageFormat, int page) throws PrinterException { 

    deepCopyString = string; 

    FontMetrics metrics = graphics.getFontMetrics(font); 
    int lineHeight = metrics.getHeight(); 

    arrangePage(graphics, pageFormat, metrics); 

    if (page > pageBreaks.length){ 
     return NO_SUCH_PAGE; 
    } 

    Graphics2D g = (Graphics2D) graphics; 

    g.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); 
    g.setFont(font); 

    int begin = (page == 0) ? 0 : pageBreaks[page-1]; 
    int end = (page == pageBreaks.length) ? lines.length : pageBreaks[page]; 

    int y = 0; 
    int x = 0; 

    for (int line = begin; line < end; line++){ 
     x = 0; 
     y += lineHeight; 

     checkSyntax(line); 

     String l = lines[line]; 

     for (int c = 0; c < l.length(); c++){ 
      applySyntax(c, line); 

      metrics = graphics.getFontMetrics(font); 
      String ch = Character.toString(l.charAt(c)); 

      g.setFont(font); 
      g.drawString(ch, x, y); 

      x += metrics.charWidth(l.charAt(c)); 
      //System.out.println(c + "/"+l.length()); 
     } 

     //g.drawString(lines[line], 0, y); 
    } 

    reset(); 

    records.add(g); 

    return PAGE_EXISTS; 
} 

你已经可以看到图形对象被记录,这样我可以在另一个组件画他们,但是它是相当无用看到,因为它会请在记录完成之前将它们发送到我的打印机。

这可能是一个糟糕的主意,而且我对打印很陌生。如果这真的是一个不好的方法去解决这个问题,请随时指引我解释一个更好的方法。

回答

3

基本上,你想创建你自己的Graphics上下文,你可以画。您还需要构建可以通过print方法的PageFormat

enter image description here

public class TestPrint implements Printable { 

    private BufferedImage background; 
    public static final float DPI = 72; 

    public static void main(String[] args) { 
     new TestPrint(); 
    } 

    public TestPrint() { 

     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (Exception ex) { 
       } 

       try { 
        background = ImageIO.read(new File("C:/Users/shane/Dropbox/MegaTokyo/MgkGrl_Yuki_by_fredrin.jpg")); 
       } catch (IOException ex) { 
        ex.printStackTrace(); 
       } 

       float width = cmToPixel(21f, DPI); 
       float height = cmToPixel(29.7f, DPI); 

       Paper paper = new Paper(); 
       float margin = cmToPixel(1, DPI); 
       paper.setImageableArea(margin, margin, width - (margin * 2), height - (margin * 2)); 
       PageFormat pf = new PageFormat(); 
       pf.setPaper(paper); 

       BufferedImage img = new BufferedImage(Math.round(width), Math.round(height), BufferedImage.TYPE_INT_RGB); 
       Graphics2D g2d = img.createGraphics(); 
       g2d.setColor(Color.WHITE); 
       g2d.fill(new Rectangle2D.Float(0, 0, width, height)); 
       try { 
        g2d.setClip(new Rectangle2D.Double(pf.getImageableX(), pf.getImageableY(), pf.getImageableWidth(), pf.getImageableHeight())); 
        print(g2d, pf, 0); 
       } catch (PrinterException ex) { 
        ex.printStackTrace(); 
       } 
       g2d.dispose(); 

       JFrame frame = new JFrame("Test"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new JLabel(new ImageIcon(img))); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 

      } 
     }); 

    } 

    public float cmToPixel(float cm, float dpi) { 

     return (dpi/2.54f) * cm; 

    } 

    public int print(Graphics graphics, PageFormat pageFormat, int page) throws PrinterException { 

     if (page > 0) { 
      return NO_SUCH_PAGE; 
     } 

     Graphics2D g = (Graphics2D) graphics; 

     g.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); 
     if (background != null) { 

      int x = (int)Math.round((pageFormat.getImageableWidth() - background.getWidth())/2f); 
      int y = (int)Math.round((pageFormat.getImageableHeight() - background.getHeight())/2f); 

      g.drawImage(background, x, y, null); 

     } 

     g.setColor(Color.BLACK); 
     g.draw(new Rectangle2D.Double(0, 0, pageFormat.getImageableWidth() - 1, pageFormat.getImageableHeight() - 1)); 

     return PAGE_EXISTS; 
    } 
} 

现在,很明显,有将要区别什么是打印在屏幕上,什么是打印到打印机,因为我们实际上并没有使用相同的硬件设备,但基本概念适用

+1

那么,如果我直接从可打印对象调用print()方法,那么它实际上不会将纸张发送给打印机呢? – Brayden

+1

不,它会使用您提供的图形上下文来渲染 - 这是一种经典的打印预览方法... – MadProgrammer

+0

非常感谢您的协助。 – Brayden