Почему этот код Java Page Printing чрезвычайно медленный и есть ли альтернатива ему?

Я использую интерфейс для печати. Точный код для PrintPanel, который реализует Printable:

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 секунд, а для набора для печати = 3–6 секунд), что означает, что оператор printJob.printDialog() занимает время. Что может быть причиной?

  4. Как свидетельствуют другие вопросы, печать на Java кажется медленной. Если да, есть ли какой-нибудь другой API для печати страниц в Java, который я мог бы использовать?

  5. Даже когда я добавил только один printableImage, функция print(), кажется, вызывается несколько раз ( 2-3 раза), о чем свидетельствует "введенная команда печати" на консоли. Это правильно?
  6. Несмотря на то, что весь printDocument() запускается в отдельном потоке, он ЗАЯВЛЯЕТ МОЕ ПРИЛОЖЕНИЕ. Как это может случиться. Что я здесь не так делаю?

0 ответов

Другие вопросы по тегам