2012-08-09 43 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