为什么此Java Page Printing代码如此之慢,还有其他替代方法吗?

时间:2018-09-09 08:37:28

标签: java java-print

我正在使用Printable界面。实现了Printable的 PrintPanel 的确切代码是:

package accessory;

// all necessary imports

public class PrintPanel implements Printable {

BufferedImage printableImages[] = null;
DynPanel printable = null;

public Font printFont = new Font("Arial", Font.BOLD , 10);
public String headerStr = null , footerStr = null;
public boolean draw_pageBorder = false;
public Color borderColor = Color.BLACK;
public int pageBorder_thickness = 2;
public int pageCount = 1;

public PrintPanel(DynPanel panel)
{
printable = panel;
pageCount = 1;
}
public PrintPanel(BufferedImage images[])
{
printableImages = images;
pageCount = images.length;
}
    @Override
   public int print(Graphics g, PageFormat pageFormat, int page) throws PrinterException
{
 System.out.println("entered print command");
 if(page < pageCount )
 {

 //--- Create the Graphics2D object
 Graphics2D g2d = (Graphics2D) g;
 g2d.translate(pageFormat.getImageableX(), pageFormat
         .getImageableY());
 //--- Translate the origin to 0,0 for the top left corner

 int fontHeight = g2d.getFontMetrics().getHeight();
 int fontDescent = g2d.getFontMetrics().getDescent();
 int lineHeight = fontHeight+ fontDescent;

 int fontWidth_header = g2d.getFontMetrics().stringWidth(headerStr);
 int fontWidth_footer = g2d.getFontMetrics().stringWidth(footerStr);
 int remainder_header = (int)Math.ceil( pageFormat.getImageableWidth()  )  - fontWidth_header;
 remainder_header /= 2d;
 int remainder_footer = (int)Math.ceil( pageFormat.getImageableWidth()  )  - fontWidth_footer;
 remainder_footer /= 2d;

  if(draw_pageBorder)
  {

 g2d.setPaint(borderColor);


 g2d.setStroke(new BasicStroke(pageBorder_thickness));
 Rectangle2D.Double border = new Rectangle2D.Double(0, 0, pageFormat
     .getImageableWidth()+4, pageFormat.getImageableHeight()+4);

   g2d.draw(border);
  }
  g2d.setFont(printFont);



 // code for printing DynPanel (JPanel)
 if(printable != null)
 {

      Dimension compSize = printable.getPreferredSize();
         // Make sure we size to the preferred size
         printable.setSize(compSize);
         // Get the the print size
         Dimension printSize = new Dimension();
         printSize.setSize(pageFormat.getImageableWidth(), pageFormat.getImageableHeight());

         // Calculate the scale factor
         double scaleFactor = getScaleFactorToFit(compSize, printSize);
         // Don't want to scale up, only want to scale down
         if (scaleFactor > 1d) {
             scaleFactor = 1d;
         }


         // Calculate the scaled size...
         double scaleWidth = compSize.width * scaleFactor;
         double scaleHeight = compSize.height * scaleFactor;

         // Create a clone of the graphics context.  This allows us to manipulate
         // the graphics context without begin worried about what effects
         // it might have once we're finished
         //Graphics2D g2d = (Graphics2D) g.create();
         // Calculate the x/y position of the component, this will center
         // the result on the page if it can
         double x = ((pageFormat.getImageableWidth() - scaleWidth) / 2d) + pageFormat.getImageableX();
         double y = ((pageFormat.getImageableHeight() - scaleHeight) / 2d) + pageFormat.getImageableY();
 AffineTransform at = new AffineTransform();
 // Translate the offset to out "center" of page
 at.translate(x, y);
 // Set the scaling
 at.scale(scaleFactor, scaleFactor);
 // Apply the transformation
 g2d.transform(at);
 // Print the component

 printable.printAll(g2d);
 }
 else // code for printing BufferedImages 'printableImages'
 {


     try{



            int width = (int) pageFormat.getImageableWidth();
            int height = (int) pageFormat.getImageableHeight();
            int imageWidth  = printableImages[page].getWidth();
            int imageHeight = printableImages[page].getHeight();

            double scaleX = (double)width/imageWidth;
            double scaleY = (double)height/imageHeight;
            AffineTransform scaleTransform = AffineTransform.getScaleInstance(scaleX, scaleY);
            AffineTransformOp bilinearScaleOp = new AffineTransformOp(scaleTransform, AffineTransformOp.TYPE_BILINEAR);

            printableImages[page] = bilinearScaleOp.filter(
                    printableImages[page],
                new BufferedImage(width, height, printableImages[page].getType()));
         System.out.println("Printing IMAGE="+printableImages[page]);

        g2d.drawImage(printableImages[page] ,  (int)pageFormat.getImageableX() , ( (int)pageFormat.getImageableY() + (8 + lineHeight) ),  null);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        System.out.println("ERROR IN PRINTING IMAGE");
        e.printStackTrace();
    }

 }
 if(headerStr != null)
     g2d.drawString( headerStr , (int)pageFormat.getImageableX() + remainder_header , (int)pageFormat.getImageableY() + (8 + lineHeight));
     if(footerStr != null)
     {
      if(footerStr.equals("print_page_index"))
          g2d.drawString( ("Page "+( page + 1) + " of " + pageCount ) , (int)pageFormat.getImageableX() + remainder_footer , (int)pageFormat.getImageableY() + ((int)pageFormat.getImageableHeight() - lineHeight - 8 ));
      else 
     g2d.drawString( footerStr ,  (int)pageFormat.getImageableX() + remainder_footer , (int)pageFormat.getImageableY() + ((int)pageFormat.getImageableHeight() - lineHeight - 8));
     }
//else System.out.println("EMPTY PRINT");
 //g2d.dispose();
if(printable != null) printable.revalidate();
  //  printable.paint(g2d);
 return Printable.PAGE_EXISTS;
}
else return Printable.NO_SUCH_PAGE;

     }



 }

我正在使用构造函数PrintPanel(BufferedImage images [])

  • 现在,我正在调用具有以下代码的函数printDocument():

    private void printDocument()
    {
    
    
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
    
            System.out.println("Initiating print command..");
            long t1 = System.currentTimeMillis();                
            PrinterJob printJob = PrinterJob.getPrinterJob();
            Book book = new Book();
            PageFormat documentPageFormat = new PageFormat();
            documentPageFormat.setOrientation(PageFormat.PORTRAIT);
           BufferedImage pages[] = new BufferedImage[pane.pageCount];
    
            for(int count = 0; count < pane.pageCount; count ++ )   
             pages[count] = pane.pages[count].getSnapshot();
    
    
    
            PrintPanel printImage = new PrintPanel(pages);
    
            printImage.headerStr = "Java Study Frame : " + ( docName != null ? (( docName.replaceAll("\\s+" , "").isEmpty() ? " Untitled JSF Document " : docName ) ) : " Untitled JSF Document " ) ;
            printImage.footerStr = "print_page_index";
    
           printJob.setJobName("Java Study Frame Print");
           long t2 = System.currentTimeMillis();
            System.out.println("Setting printable. Prev time = " + (t2 - t1)/1000 +" seconds!");
            t1 = System.currentTimeMillis();
            printJob.setPrintable(printImage);
             t2 = System.currentTimeMillis();
            System.out.println("Printable set in " + (t2 - t1)/1000 + " seconds !");
    
            if (printJob.printDialog()) {
              try {
                printJob.print();
              } catch (Exception PrintException) {
                PrintException.printStackTrace();
              }
            }
        }
    }); 
    

    }

我的问题

  1. 从字面上看 超过30秒 每次,打印对话框在之后之后出现启动打印命令”打印到控制台上。是什么原因造成的?
  2. 即使单击“打印”对话框中的“打印”按钮,它实际上至少需要40-50秒才能实际生成打印作业。这是为什么 ? (我最多打印1-2页)
  3. 到达setPrintable()大约需要3到6秒钟(上一个时间= 0秒钟,Printable Set等于3600到6秒钟),这意味着 语句printJob.printDialog( )需要时间 。可能是什么原因造成的?

  4. 从其他问题可以看出,Java打印似乎很慢。如果是这样, 还有其他我可以使用的Java Java页面打印API 吗?

  5. 即使我只添加了一个printableImage,函数print()似乎也被调用了多次(2-3次),如控制台上的“输入的打印命令”所证明的那样。正确吗?
  6. 虽然整个printDocument()是 在单独的线程中启动的 ,但它挂起了我的应用程序。怎么会这样我在这里做什么错了?

0 个答案:

没有答案