2017-04-19 7 views
0

私はJava SE 8デスクトップアプリケーションを作成しています。私は、Eclipse IDE、OracleのJDKを使用し、MS Windows 10 OS上で実行します。MS Windows 10サービスを使用してpdfに印刷すると厄介な図が得られる

私のアプリは略図を描きます。 JTabbedPaneの一部となるJPanelの図を描きます。それはGUI上でうまく表示され、非常に反応します。図を印刷サービスに渡すと、問題が表示されます。しかし、それをプリンタに印刷する代わりに、「Microsoft印刷から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()となっているのでしょうか?異なるサイズの値を返しますか?もう一つのことは、私が上に示したようにこのメソッドをオーバーライドしたことです。また、ダイアグラムオブジェクトは1回だけ作成され、再計算は行われません。

ここで私はダイアグラムobjを作成します。スイングワーカーではアプリケーションのライフサイクルごとに1回だけ実行されます。

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ファイルに保存/印刷するときの図をきれいに表示されるようにする方法:要約中のSO

    、?

  2. ダイアグラムサイズを複数の呼び出しごとに一貫して計算するにはどうすればよいですか?ダイアグラムサイズの値が異なると、複数のコールで同じダイアグラムオブジェクトインスタンスからダイアグラムサイズを取得できますか?

答えて

0

私は問題の内容を把握しました。

図を描画するときに、 paintComponent(Graphics g)メソッドが繰り返し呼び出されていることがわかりました。ダイアグラムを何度も何度も再描画し続けます。これはシステムによって暗黙に呼び出されますが、私の実装はそれを引き起こしていました。

このトリガは、派生したJPanelオブジェクトのメソッドthis.setSize(width, height)の形式で提供されます。したがって、paintComponent(Graphics g)が再度実行されるたびにJPanelのサイズが設定されますが、それでもpainComponentメソッドの追加実行がトリガーされます。結局のところ、それは無限ループです。

そして、この無限の実行が問題の原因でした。 pdfファイルで歪んだダイアグラム画像を生成していました。

ソリューション:setSizeメソッドは必要なときにのみ実行してください。初期パネル設定時、またはサイズ変更時に表示されます。

関連する問題