2017-04-19 43 views
0

我一直在编写Java SE 8桌面应用程序。我使用Eclipse IDE,Oracle的JDK,并在MS Windows 10操作系统上运行它。当使用MS Windows 10服务打印PDF时出现凌乱图

我的应用程序总结了图表。我在JPanel上绘制了一个图,该图成为JTabbedPane的一部分。它在GUI上显示得很好,而且响应速度非常快。当我通过打印服务的图表时出现问题。但是,我选择“微软打印成PDF”服务,而不是打印在打印机上。接下来发生的事情是,如果图表很大,当您向下滚动时,您会发现其质量下降。也就是说,网格开始消失,出现新的线条等。

图片在这里。 enter image description here

正如你所看到的,最终垂直网格消失,对角线逐渐蔓延,后来变得更糟。这是不受欢迎的。

在这里的相关代码:

public final class GanttChartDiagram extends TopDiagram{ 
@Override 
    public void paintComponent(Graphics graph){ 
     super.paintComponent(graph); 

     Graphics2D g2D = (Graphics2D)graph; 

     g2D.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); 
........... 

@Override 
    public Dimension getPreferredSize(){ 
     return new Dimension(this.diagramWidth + 20, this.diagramHeight + 20); 
    } 
} 
} 

getPreferredSize()方法识别图表的大小,从而使应用程序知道如何调整相应的滚动条,以适应在图表中,否则默认情况下它返回0。 ,如果没有被覆盖。 这是我绘制图表的类。

超类在这里:

public abstract class TopDiagram extends JPanel implements Printable { 
    private static final long serialVersionUID = 1469816888488484L; 

    @Override 
    public void paintComponent(Graphics graph){ 
     super.paintComponent(graph); 
    }; 

    /** 
    * Prints selected diagram 
    */ 
    @Override 
    public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException { 

     Graphics2D dimension = (Graphics2D)graphics; 
     dimension.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); 

     if(pageIndex < PrintingImageBuffer.getImageBuffer().size()){ 
      dimension.drawImage(PrintingImageBuffer.getImageBuffer().get(pageIndex), null, 0, 0); 
      return PAGE_EXISTS; 
     } 
     else{ 
      return NO_SUCH_PAGE; 
     }    
    } 
} 

现在是我打印图:

public static void printDiagram(){ 
    new Thread(new Runnable(){ 

    public void run(){ 

    TopDiagram diagram = null; 
        if(id.equalsIgnoreCase("GanttChart")){ 
         diagram = ganttChartDiagram; 
    } 

     final PrinterJob printer = PrinterJob.getPrinte 

rJob(); 
         printer.setJobName("Printing the "+id+" Diagram"); 
         PageFormat format = printer.pageDialog(page); 

         int nowWidth = (int)diagram.getPreferredSize().getWidth(); 
         int nowHeight = (int)diagram.getPreferredSize().getHeight(); 

         BufferedImage buffImg = new BufferedImage(nowWidth, nowHeight, BufferedImage.TYPE_INT_ARGB);//default type 

         Graphics2D d = (Graphics2D)buffImg.getGraphics(); 

    ....etc.................. 
    } 

    }).start(); 
    } 

现在最有趣的部分是这样的:

int nowWidth = (int)diagram.getPreferredSize().getWidth(); 
         int nowHeight = (int)diagram.getPreferredSize().getHeight(); 

在图的相同实例,在多次打印(或在方法内)调用时,它可能会或可能不会返回不同的值。所以这会导致我出现某种Raster异常。但是我设法通过调用size方法一次来消除该异常,并在整个方法中重用该大小值。因此,尺寸值保持不变,因此只能读取一次。 糟糕的解决方案,但它的工作原理。

我也想解决这个问题。首先,如何在图obj的同一实例上调用diagram.getPreferredSize().getWidth()。返回不同的大小值?还有一件事,就是我否定了上面介绍的这种方法。图表对象只创建一次,不需要重新计算。

这是我创建的图表OBJ。每个应用程序的生命周期只有一次Swing Worker。

GanttChartSwingWorker ganttSwingWorker = new GanttChartSwingWorker(GanttChartDiagram::new, tabbedPane, showPerformanceDiagramTab, ganttChartDiagramTabReady); 
     ganttSwingWorker.execute(); 

     new Thread(() -> {  
      try{ 
       ganttChartDiagramTabReady.await();    
       ganttChartDiagram = ganttSwingWorker.getGanttChartDiagram();     

      }catch(InterruptedException ie){ie.printStackTrace();} 
     } 
     ).start(); 

摇摆工人部分:

diagram = this.get(); 

       JScrollPane scrollPaneChart = addScrollPane(diagram);    
       tabbedPane.addTab("Gantt Chart", null, scrollPaneChart, "Displays Gantt Chart Diagram"); 

一些图的对象可以是耗时的创建,规定延迟,所以我使用Swing工人这样做。

因此,简言之:

  1. 如何使图出现干净当我打印/保存PDF文件在我解释的方式吗?
  2. 如何根据多个调用使图表大小一致地计算?是什么导致不同的图表大小值在多次调用中从相同的图表对象实例中检索它?

回答

0

我刚才发现了什么问题。

我注意到,在绘制图表时, paintComponent(Graphics g)方法已被重复调用。它不断重复绘制图表。它由系统隐含地调用,但是我的实现一直在触发它。

并且该触发器以衍生JPanel对象的this.setSize(width, height)方法的形式出现。因此,每次paintComponent(Graphics g)重新执行时,它会在JPanel上设置它的大小,但尚未触发painComponent方法的额外执行。最后,这是一个无限循环。

而且无限的执行是问题的原因;它在pdf文件上产生扭曲的图表图像。

解决方案:仅在需要时执行setSize方法;在初始面板设置或调整大小。