2

在此处输入图像描述

我的 SWT TitleAreaDialog 中有一个打印按钮。

viewPDFButton.addSelectionListener(new SelectionAdapter() {
     public void widgetSelected(SelectionEvent e) {
        try {

           startPdfPrintOperation();
        }
        catch (Exception e1) {
           // TODO Auto-generated catch block
           e1.printStackTrace();
        }
     }
  }); 

我从表中的用户选择中获取现有的 PDF 文件名和路径。然后我希望将 pdf 文件打印到本地打印机。需要允许用户选择本地打印机。

public void startPdfPrintOperation() throws Exception {
  File file = new File(getPDFFileName());
  RandomAccessFile raf;
  raf = new RandomAccessFile(file, "r");
  FileChannel channel = raf.getChannel();
  ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
  pdfFile = new PDFFile(buf);
  PDFPrintPage pages = new PDFPrintPage(pdfFile);

  // Create Print Job
  pjob = PrinterJob.getPrinterJob();
  pjob.setPrintable(new MyPrintable());
  final HashPrintRequestAttributeSet attset;
  attset = new HashPrintRequestAttributeSet ();
  attset.add (new PageRanges (1, pdfFile.getNumPages ()));
  if (pjob.printDialog (attset)) {
      try {
           pjob.print (attset);
      }
      catch (PrinterException e) {
           e.printStackTrace();
      }
  }             
}
class MyPrintable implements Printable {
  public int print (Graphics g, PageFormat format, int index) throws PrinterException {
     int pagenum = index+1;
        if (pagenum < 1 || pagenum > pdfFile.getNumPages ())
            return NO_SUCH_PAGE;

        Graphics2D g2d = (Graphics2D) g;
        AffineTransform at = g2d.getTransform ();
        PDFPage pdfPage = pdfFile.getPage (pagenum);

        Dimension dim;
        dim = pdfPage.getUnstretchedSize ((int) format.getImageableWidth (),
                                       (int) format.getImageableHeight (),
                                       pdfPage.getBBox ());

        Rectangle bounds = new Rectangle ((int) format.getImageableX (),
                                       (int) format.getImageableY (),
                                       dim.width,
                                       dim.height);

        PDFRenderer rend = new PDFRenderer (pdfPage, (Graphics2D) g, bounds, null, null);

        try
        {
           pdfPage.waitForFinish ();
           rend.run ();
        }
        catch (InterruptedException ie)
        {
           MessageDialog.openError(null, "PDF Error Message", "Needs");
        }
        g2d.setTransform (at);
        g2d.draw (new Rectangle2D.Double (format.getImageableX (),
                                       format.getImageableY (),
                                       format.getImageableWidth (),
                                       format.getImageableHeight ()));
     return PAGE_EXISTS;
  }
}

我从第 315 行收到上述错误

if (pjob.printDialog (attset)) {

打印机对话框打开整个应用程序被冻结并且没有响应。然后在大约 30 秒内,我收到上述错误。

我曾尝试 Display.getDefault().asyncExec(new Runnable() )在多个地方使用,但没有帮助。

可能是因为基本对话框是 SWT 而打印机对话框是 AWT?

4

1 回答 1

1

由于您没有定义“在多个位置”,我建议您在其自己的类中重构打印作业,扩展Thread并实现在run方法中启动打印作业。
我对上面代码中的所有类都不熟悉,你可以尝试简单地启动这个线程,它将与 SWT 线程并行运行。尝试避免共享资源,这可能有助于解决您的僵局。如果您想从该线程获得 UI 响应,您可以将例如 SWT 消息框(“打印完成!”)包装在对Display.getDefault().asyncExec(new Runnable() { ... }.
此外,请测试没有UI代码的打印代码是否产生相同的异常。如果是这样,则环境可能配置错误。

于 2012-11-10T11:46:15.260 回答