2012-08-09 42 views

回答

3

我二手解決trashgod,但我已經擴展解決方案,支持分頁打印的我希望能夠用我的應用程序執行。

我希望能夠像JFreechart通常一樣打印圖像,但將圖形的多個圖形放在網格中的每個頁面上,並將其拉伸並很好地展開到頁面。使用這個功能,我能夠生成的圖像下面匹配打印:

Sample Print

我基本上擴展JPanel並實現打印接口。製作一個包含我想要顯示/打印的所有JFreecharts的面板。面板將根據您提供的一些佈局指令以網格方式排列它們。

面板的打印功能基本上像正常一樣採用頁面格式,但隨後sub將頁面劃分爲之前指定的網格。然後它將每個這些單元格併爲它們中的每一個製作一個頁面格式。然後它會告訴每個JFreeChart ChartPanel打印給每個PageFormat單元格。

CustomChartPanel:

package com.company.jfreeChartCustom; 

import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GridLayout; 
import java.awt.geom.Rectangle2D; 
import java.awt.print.PageFormat; 
import java.awt.print.Paper; 
import java.awt.print.Printable; 
import java.awt.print.PrinterException; 
import java.awt.print.PrinterJob; 
import java.util.ArrayList; 
import java.util.List; 

import javax.swing.JOptionPane; 
import javax.swing.JPanel; 

import org.jfree.chart.ChartPanel; 
import org.jfree.chart.JFreeChart; 

import com.lowagie.text.Row; 

/** 
* The CustomChartPanel is used to display/print multiple JFreeCharts 
* Users should only interact with this class with the methods defined 
* below in order to get the proper functionality. Using 
* inherited methods may produce unwanted display/print behavior if you 
* add components other than JFreeCharts. 
* 
*/ 
public class CustomChartPanel extends JPanel implements Printable{ 

    List<JFreeChart> charts = new ArrayList<JFreeChart>(); 
    List<ChartPanel> panels = new ArrayList<ChartPanel>(); 
    ChartLayoutInstructions layoutInstructions; 

    public CustomChartPanel(){ 
     super(); 
    } 

    public CustomChartPanel(JFreeChart chart){ 
     super(); 
     charts.add(chart); 
    } 

    /** 
    * Creates a CustomChartPanel which displays 1 or more charts in a grid-like fashion 
    * described by the layoutInstructions you pass in. Note that if you pass in more 
    * charts than there are columns specified in the ChartLayoutInstructions then excess 
    * charts will not be displayed or printed. 
    * @param charts 
    * @param layoutInstructions 
    */ 
    public CustomChartPanel(List<JFreeChart> charts, ChartLayoutInstructions layoutInstructions){ 
     super(); 
     this.layoutInstructions = layoutInstructions; 
     for(JFreeChart chart : charts){ 
      this.charts.add(chart); 
     } 
     createUIComponents(); 
    } 

    protected void createUIComponents(){ 
     int size = Math.min(layoutInstructions.getColumns() * layoutInstructions.getRows(), charts.size()); 
     this.setLayout(new GridLayout(layoutInstructions.getRows(), layoutInstructions.getColumns())); 


     for(int i = 0; i < size; i++){ 
      System.err.println("Adding chart"); 
      ChartPanel chartPanel = new ChartPanel(charts.get(i)); 
      chartPanel.setMaximumDrawHeight(20000); 
      chartPanel.setMinimumDrawHeight(0); 
      chartPanel.setMaximumDrawWidth(20000); 
      chartPanel.setMinimumDrawWidth(0); 
      chartPanel.setPopupMenu(null); 
      panels.add(chartPanel); 
      this.add(chartPanel); 
     } 
    } 

    public void createPrintJob(){ 
     PrinterJob job = PrinterJob.getPrinterJob(); 
     PageFormat pf = job.defaultPage(); 
     PageFormat pf2 = job.pageDialog(pf); 
     if (pf2 != pf) { 
      job.setPrintable(this, pf2); 
      if (job.printDialog()) { 
       try { 
        job.print(); 
       } 
       catch (PrinterException e) { 
        JOptionPane.showMessageDialog(this, e); 
       } 
      } 
     } 
    } 

    @Override 
    public int print(Graphics g, PageFormat pf, int pageIndex) 
      throws PrinterException { 
     System.err.println("PRINTING"); 
     //Divide the current page format into sections based 
     //on the layout instructions received in the constructor 
     //a new pagelayout is created for each cell in the grid 
     //that will then be passed along to the print method of 
     //each chart panel. 


     if(pageIndex != 0){ 
      return NO_SUCH_PAGE; 
     } 

     List<PageFormat> pageFormats = new ArrayList<PageFormat>(); 

     //setup all the page formats needed for the grid cells. 
     double x = pf.getImageableX(); 
     double y = pf.getImageableY(); 
     double cellWidth = pf.getImageableWidth()/layoutInstructions.getColumns(); 
     double cellHeight = pf.getImageableHeight()/layoutInstructions.getRows(); 

     for(int i=1; i <= layoutInstructions.getRows(); i++){ 
      double rowOffset = (i-1)*cellHeight + y; 
      for(int j=1; j <= layoutInstructions.getColumns(); j++){ 
       PageFormat format = new PageFormat(); 
       Paper paper = new Paper(); 
       double columnOffset = (j-1)*cellWidth + x; 
       paper.setImageableArea(columnOffset, rowOffset, cellWidth, cellHeight); 
       format.setPaper(paper); 
       pageFormats.add(format); 
      } 
     } 

     //have each chartpanel print on the graphics context using its 
     //particular PageFormat 
     int size = Math.min(pageFormats.size(), panels.size()); 
     for(int i = 0; i < size; i++){ 
      panels.get(i).print(g, pageFormats.get(i), pageIndex); 

     } 

     return PAGE_EXISTS; 
    } 

ChartLayoutInstructions:

我有計劃擴展這個類爲我自己的目的來定義更高級的行爲。這就是爲什麼我使用這個類而不是在CustomChartPanel類的構造函數中定義行和列的原因。

package com.company.jfreeChartCustom; 

/** 
* ChartLayoutInstructions are used to specify how charts should be 
* layed out on screen and in print format. 
* 
*/ 
public class ChartLayoutInstructions { 

    int rows; 
    int columns; 

    /** 
    * Constructor 
    * @param rows number of rows in the display/print grid 
    * @param columns number of columns in the display/print grid 
    */ 
    public ChartLayoutInstructions(int rows, int columns, boolean allowSwap){ 
     this.rows = Math.abs(rows); 
     this.columns = Math.abs(columns); 
    } 

    public int getRows() { 
     return rows; 
    } 

    public void setRows(int rows) { 
     this.rows = Math.abs(rows); 
    } 

    public int getColumns() { 
     return columns; 
    } 

    public void setColumns(int columns) { 
     this.columns = Math.abs(columns); 
    } 
} 
+0

用於'工具Printable'。 – trashgod 2012-08-14 18:59:15

+0

帶有一個圖表參數的構造函數不完整。加; 'code layoutInstructions = new ChartLayoutInstructions(1,1,false); createUIComponents(); ' – kerberos84 2015-06-06 09:52:33

3

是的,只需將您的ChartPanel實例添加到具有GridLayout(0, 1)JPanel即可實現從上到下的排列。此example使用正交GridLayout(1, 0)來設置三個面板。

image

+0

AFAIK,儘管您可能想要更改水平佈局的頁面方向,但通過渲染屏幕上的內容來進行打印。 – trashgod 2012-08-14 17:15:34

+0

我用你的解決方案來顯示它們,然後定製讓它們正確打印的東西。我用另一個答案概述了我的解決方案謝謝您的幫助。 – CryptDemon 2012-08-14 18:46:59