最近做了一些关于图表方面的开发工作,现把这些开发过程记录一下,就算是留给自己看吧,估计百度也搜不到,我是用Swing开发的。哈哈,没有关系写着玩!
上带码前,先看看我做的效果如何,截图如下:
以上是相同查询条件下,所展示的不同的图表,先看看不同的图表的相关属性设置吧!上代码,对了,还可以导出图片的!
/**
* 折线图相关设置
* @param jFreeChart
*/
public static void lineChartConfig(JFreeChart jFreeChart){
CategoryPlot cp = jFreeChart.getCategoryPlot();
cp.setBackgroundPaint(ChartColor.WHITE); // 背景色设置
cp.setRangeGridlinePaint(ChartColor.GRAY); // 网格线色设置
cp.setDomainGridlinePaint(ChartColor.BLACK);
cp.setDomainGridlinesVisible(true); //设置背景网格线是否可见
cp.setNoDataMessage("暂时没有此类数据");
cp.setBackgroundPaint(new Color(255, 255, 204));
// 数据轴属性部分
NumberAxis rangeAxis = (NumberAxis) cp.getRangeAxis();
rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
rangeAxis.setAutoRangeIncludesZero(true); // 自动生成
rangeAxis.setUpperMargin(0.20);
rangeAxis.setLabelAngle(Math.PI / 2.0);
rangeAxis.setAutoRange(false);
// 获取图表区域对象
CategoryPlot plot = (CategoryPlot) jFreeChart.getPlot();
// XYLineAndShapeRenderer xylinerenderer = (XYLineAndShapeRenderer)plot.getRenderer();
// xylinerenderer.setBaseShapesVisible(true);
// 数据渲染部分 主要是对折线做操作
LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot.getRenderer();
//设置曲线是否显示数据点
renderer.setBaseShapesVisible(true);
renderer.setBaseItemLabelsVisible(true);
renderer.setSeriesPaint(0, Color.red); // 设置折线的颜色
renderer.setBaseShapesFilled(true);
renderer.setBaseItemLabelsVisible(true);
renderer.setBasePositiveItemLabelPosition(
new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_LEFT));
renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
jFreeChart.getTitle().setFont(new Font("宋体", Font.BOLD, 15));
jFreeChart.getLegend().setItemFont(new Font("黑体", Font.BOLD, 15));
CategoryAxis domainAxis = plot.getDomainAxis();
/*------设置X轴坐标上的文字-----------*/
domainAxis.setTickLabelFont(new Font("黑体", Font.PLAIN, 14));
/*------设置X轴的标题文字------------*/
domainAxis.setLabelFont(new Font("宋体", Font.PLAIN, 14));
NumberAxis numberaxis = (NumberAxis) plot.getRangeAxis();
plot.getDomainAxis().setCategoryLabelPositions(CategoryLabelPositions.UP_45);
/*------设置Y轴坐标上的文字-----------*/
numberaxis.setTickLabelFont(new Font("黑体", Font.PLAIN, 14));
/*------设置Y轴的标题文字------------*/
numberaxis.setLabelFont(new Font("黑体", Font.PLAIN, 14));
}
/**
* 饼图相关设置
* @param jFreeChart
*/
public static void barChartConfig(JFreeChart jFreeChart){
Plot plot = jFreeChart.getPlot();
plot.setBackgroundPaint(new Color(255, 255, 204));
plot.setNoDataMessage("暂时没有此类数据");
// 处理图形上的乱码
// 处理主标题的乱码
jFreeChart.getTitle().setFont(new Font("宋体", Font.BOLD, 18));
// 处理子标题乱码
// jFreeChart.getLegend().setItemFont(new Font("宋体", Font.BOLD, 15));
// 获取图表区域对象
CategoryPlot categoryPlot = (CategoryPlot) jFreeChart.getPlot();
// 获取X轴的对象
CategoryAxis3D categoryAxis3D = (CategoryAxis3D) categoryPlot.getDomainAxis();
// 获取Y轴的对象
NumberAxis3D numberAxis3D = (NumberAxis3D) categoryPlot.getRangeAxis();
// 处理X轴上的乱码
categoryAxis3D.setTickLabelFont(new Font("宋体", Font.BOLD, 15));
// 设置X轴标签倾斜45度显示
categoryAxis3D.setCategoryLabelPositions(CategoryLabelPositions.UP_45);
// 处理X轴外的乱码
categoryAxis3D.setLabelFont(new Font("宋体", Font.BOLD, 15));
// 处理Y轴上的乱码
numberAxis3D.setTickLabelFont(new Font("宋体", Font.BOLD, 15));
// 处理Y轴外的乱码
numberAxis3D.setLabelFont(new Font("宋体", Font.BOLD, 15));
// 处理Y轴上显示的刻度,以10作为1格
numberAxis3D.setAutoTickUnitSelection(false);
NumberTickUnit unit = new NumberTickUnit(2);
numberAxis3D.setTickUnit(unit);
// 获取绘图区域对象
CustomRenderer renderer = new CustomRenderer();
// 设置每个地区所包含的平行柱的之间距离
renderer.setItemMargin(0.5);
// 在图形上显示数字
renderer.setBaseItemLabelGenerator(new
StandardCategoryItemLabelGenerator());
renderer.setBaseItemLabelsVisible(true);
renderer.setBaseItemLabelFont(new Font("宋体", Font.BOLD, 15));
renderer.setMaximumBarWidth(0.07);
jFreeChart.getRenderingHints().put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
// 显示每个柱的数值,并修改该数值的字体属性
renderer.setIncludeBaseInRange(true);
categoryPlot.setRenderer(renderer);
// 设置柱的透明度
categoryPlot.setForegroundAlpha(1.0f);
// 背景色 透明度
categoryPlot.setBackgroundAlpha(0.5f);
}
/**
* 饼图相关设置
* @param jFreeChart
*/
public static void pieChartConfig(JFreeChart jFreeChart){
// 处理主标题的乱码
jFreeChart.getTitle().setFont(new Font("宋体", Font.BOLD, 18));
// 处理子标题乱码
jFreeChart.getLegend().setItemFont(new Font("宋体", Font.BOLD, 15));
PiePlot plot = (PiePlot) jFreeChart.getPlot();
// 设置饼状图体里的的各个标签字体
plot.setLabelFont(new Font("宋体", Font.BOLD, 12));
plot.setNoDataMessage("暂时没有此类数据");
//设置百分比
plot.setLabelGenerator(new StandardPieSectionLabelGenerator(
"{0} {2}",
NumberFormat.getNumberInstance(),
new DecimalFormat("0.00%")));
}
柱形图,每个柱子的颜色是不同的,为了实现这效果,还是写了一段代码,有继承关系,如下:
public class CustomRenderer extends org.jfree.chart.renderer.category.BarRenderer {
/**
*
*/
private static final long serialVersionUID = 784630226449158436L;
private Paint[] colors;
//初始化柱子颜色
private String[] colorValues = { "#87CEFA", "#B0C4DE", "#8470FF", "#8B4513", "#FF00FF", "#FFF5EE" };
public CustomRenderer() {
colors = new Paint[colorValues.length];
for (int i = 0; i < colorValues.length; i++) {
colors[i] = Color.decode(colorValues[i]);
}
}
//每根柱子以初始化的颜色不断轮循
public Paint getItemPaint(int i, int j) {
return colors[j % colors.length];
}
}
这样就实现了每个柱子的颜色不同,我将柱子的颜色设置和图表属性的设置写在同一个类里了,下面再来看看后台所支持的数据
当然了,数据表还有外键,现在就不多说了,结构已经给了,下面看看后台查询,上代码:
public Map<Object, Number> statMaterialChecks(int type, Equipment parent, Date from, Date to, String normalFlag,
int codeType) {
Map<Object, Number> map = new TreeMap<>();
String sql = null;
if (type == 1) {
Map ok = statMaterialChecks(11, parent, from, to, normalFlag, codeType);
Map ng = statMaterialChecks(12, parent, from, to, normalFlag, codeType);
ok.putAll(ng);
return ok;
}
if (type == 2) {
Map empty = statMaterialChecks(21, parent, from, to, normalFlag, codeType);
Map notempty = statMaterialChecks(22, parent, from, to, normalFlag, codeType);
empty.putAll(notempty);
return empty;
}
switch (type) {
case 1:// 按结果
sql = "SELECT COUNT(*),normalFlag FROM MaterialCheck WHERE (1=1)";
break;
// case : //
// sql = "SELECT COUNT(*),material.assignedCode FROM MaterialCheck WHERE
// (1=1)";
// break;
case 11: //
sql = "SELECT COUNT(*),'OK' FROM MaterialCheck WHERE (1=1)";
break;
case 12: //
sql = "SELECT COUNT(*),'NG' FROM MaterialCheck WHERE (1=1)";
break;
case 21: //
sql = "SELECT COUNT(*),'无编码' FROM MaterialCheck WHERE (1=1)";
break;
case 22: //
sql = "SELECT COUNT(*),'有编码' FROM MaterialCheck WHERE (1=1)";
break;
default:// 按天
sql = "SELECT COUNT(*),DATE(finishTime) FROM MaterialCheck WHERE (1=1)";
}
List params = new ArrayList();
int i = 0;
if (parent != null) {
sql = sql + " AND equipment.id=?" + i;
i++;
params.add(parent.getId());
}
Calendar c = Calendar.getInstance();
if (from != null) {
c.setTime(from);
c.set(Calendar.HOUR, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
sql = sql + " AND beginTime>=?" + i;
i++;
params.add(c.getTime());
}
if (to != null) {
c.setTime(to);
c.set(Calendar.HOUR, 24);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
sql = sql + " AND finishTime<=?" + i;
i++;
params.add(c.getTime());
}
// 正常标志
if ("OK".equals(normalFlag)) {
sql = sql + " AND normalFlag=true";
} else if ("NG".equals(normalFlag)) {
sql = sql + " AND normalFlag=false";
}
// 物料编码
if (codeType == 1) {
sql = sql + " AND (material.assignedCode IS NULL OR material.assignedCode='')";
} else if (codeType == 2) {
sql = sql + " AND (material.assignedCode IS NOT NULL AND material.assignedCode<>'')";
}
switch (type) {
case 1:// 按结果
sql = sql + " GROUP BY normalFlag";
break;
// case 3: //
// sql =sql+ " GROUP BY material.assignedCode";
// break;
case 11: //
sql = sql + " AND normalFlag=true GROUP BY 'OK'";
break;
case 12: //
sql = sql + " AND normalFlag=false GROUP BY 'NG'";
break;
case 21: //
sql = sql + " AND (material.assignedCode IS NULL OR material.assignedCode='') GROUP BY '无编码'";
break;
case 22: //
sql = sql + " AND (material.assignedCode IS NOT NULL AND material.assignedCode<>'') GROUP BY '有编码'";
break;
default:// 按天
sql = sql + " GROUP BY DATE(finishTime)";
}
List objects = getEntityDMO().getObjects(sql, params.toArray());
for (int j = 0; j < objects.size(); j++) {
Object[] object = (Object[]) objects.get(j);
map.put(object[1], (Number) object[0]);
}
return map;
}
前台调用如下:
/*
* $Author$
* $Revision$
* $Date$
* 版权所有
* 北京XXX科技有限公司
* 中国 北京
*/
package com.ringchi.ria.app.frames;
import java.awt.BorderLayout;
import java.awt.Desktop;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.Map;
import java.util.Map.Entry;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.apache.log4j.Logger;
import org.jdesktop.fuse.InjectedResource;
import org.jdesktop.fuse.ResourceInjector;
import org.jdesktop.swingx.JXDatePicker;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;
import com.ringchi.ria.app.IRiaConsts;
import com.ringchi.ria.app.RiaApplication;
import com.ringchi.ria.app.core.RiaModel;
import com.ringchi.ria.app.ui.ChartsOverlay;
import com.ringchi.ria.util.WidgetUtil;
public class ChartsFrame extends JInternalFrame {
private static Logger log = Logger.getLogger(ChartsFrame.class);
@InjectedResource
private Font hintFont;
private JComponent topParent;
private JXDatePicker beginDate, endDate;
private JComboBox resultType, codeType; // 按OK,NG方式统计
private JComboBox chartType, statType;// 图表类型:柱状图,饼图,线图
private JPanel chartParentPanel;
private JFreeChart chart;
public ChartsFrame(JComponent topParent) {
super("统计分析", true, true, true, false);
ResourceInjector.get().inject(this);
this.topParent = topParent;
this.setFont(hintFont);
this.setAutoscrolls(true);
init();
}
public void doDefaultCloseAction() {
RiaApplication.getInstance().removeOverlay(ChartsOverlay.class);
super.doDefaultCloseAction();
}
private void init() {
JPanel innerPanel = new JPanel();
this.add(innerPanel, BorderLayout.NORTH);
innerPanel.setOpaque(false);
innerPanel.setLayout(new GridLayout(2, 8));
this.add(innerPanel, BorderLayout.NORTH);
// queryMethod = new JLabel("统计方式");
// queryMethod.setFont(hintFont);
// innerPanel.add(queryMethod, new GridBagConstraints(0, 0, 1, 1, 0, 0,
// GridBagConstraints.WEST,
// GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
JLabel infoLabel = new JLabel("开始日期");
infoLabel.setFont(hintFont);
infoLabel.setHorizontalAlignment(SwingConstants.RIGHT);
innerPanel.add(infoLabel);// , new GridBagConstraints(0, 1, 1, 1, 0, 0,
// GridBagConstraints.WEST,
// GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
beginDate = new JXDatePicker();
beginDate.setFont(hintFont);
beginDate.setDate(new Date());
innerPanel.add(beginDate);// , new GridBagConstraints(1, 1, 2, 1, 1.0,
// 1.0, GridBagConstraints.EAST,
// GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
infoLabel = new JLabel("截止日期");
infoLabel.setFont(hintFont);
infoLabel.setHorizontalAlignment(SwingConstants.RIGHT);
innerPanel.add(infoLabel);// , new GridBagConstraints(4, 1, 1, 1, 0, 0,
// GridBagConstraints.WEST,
// GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
endDate = new JXDatePicker();
endDate.setFont(hintFont);
endDate.setDate(new Date());
innerPanel.add(endDate);// , new GridBagConstraints(5, 1, 2, 1, 1.0,
// 1.0, GridBagConstraints.EAST,
// GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
infoLabel = new JLabel("检测结果");
infoLabel.setFont(hintFont);
infoLabel.setHorizontalAlignment(SwingConstants.RIGHT);
innerPanel.add(infoLabel);// , new GridBagConstraints(7, 1, 1, 1, 0, 0,
// GridBagConstraints.WEST,
// GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
resultType = new JComboBox(new String[] { "全部", "OK", "NG" });
resultType.setFont(hintFont);
innerPanel.add(resultType);// , new GridBagConstraints(8, 1, 1, 1, 0.0,
// 0.0, GridBagConstraints.WEST,
// GridBagConstraints.NONE, new Insets(0, 0, 0, 5), 0, 0));
infoLabel = new JLabel("编码类型");
infoLabel.setFont(hintFont);
infoLabel.setHorizontalAlignment(SwingConstants.RIGHT);
innerPanel.add(infoLabel);// , new GridBagConstraints(9, 1, 1, 1, 0, 0,
// GridBagConstraints.WEST,
// GridBagConstraints.NONE, new Insets(0, 5, 0, 0), 0, 0));
codeType = new JComboBox(new String[] { "全部", "编码为空", "编码不为空" });
codeType.setFont(hintFont);
innerPanel.add(codeType);// new GridBagConstraints(10, 1, 1, 1, 0.0,
// 0.0, GridBagConstraints.WEST,
// GridBagConstraints.NONE, new Insets(0, 0, 0, 5), 0, 0));
infoLabel = new JLabel("统计类型");
infoLabel.setFont(hintFont);
infoLabel.setHorizontalAlignment(SwingConstants.RIGHT);
innerPanel.add(infoLabel);// , new GridBagConstraints(11, 1, 1, 1, 0, 0,
// GridBagConstraints.WEST,
// GridBagConstraints.NONE, new Insets(0, 5, 0, 0), 0, 0));
statType = new JComboBox(new String[] { "按天", "按检测结果", "按物料编码" });
statType.setFont(hintFont);
innerPanel.add(statType);// , new GridBagConstraints(12, 1, 1, 1, 0.0,
// 0.0, GridBagConstraints.WEST,
// GridBagConstraints.NONE, new Insets(0, 0, 0, 5), 0, 0));
statType.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {// 当用户的选择改变时,则在JLabel上会显示出Swing目前字形大小信息.
changeChart(chartType.getSelectedIndex());
}
}
});
infoLabel = new JLabel("图表类型");
infoLabel.setFont(hintFont);
infoLabel.setHorizontalAlignment(SwingConstants.RIGHT);
innerPanel.add(infoLabel);// , new GridBagConstraints(13, 1, 1, 1, 0, 0,
// GridBagConstraints.WEST,
// GridBagConstraints.NONE, new Insets(0, 5, 0, 0), 0, 0));
chartType = new JComboBox(new String[] { "柱状图", "饼图", "折线图" });
chartType.setFont(hintFont);
innerPanel.add(chartType);// , new GridBagConstraints(14, 1, 1, 1, 0.0,
// 0.0, GridBagConstraints.WEST,
// GridBagConstraints.NONE, new Insets(0, 0, 0, 5), 0, 0));
chartType.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {// 当用户的选择改变时,则在JLabel上会显示出Swing目前字形大小信息.
changeChart(chartType.getSelectedIndex());
}
}
});
JButton query = new JButton("查 询");
query.setFont(hintFont);
query.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
changeChart(chartType.getSelectedIndex());
// add(chartPanel, BorderLayout.CENTER);
}
});
innerPanel.add(query);// , new GridBagConstraints(15, 1, 1, 1, 0, 0,
// GridBagConstraints.WEST,
// GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
JButton exportBtn = new JButton("导出图片");
exportBtn.setFont(hintFont);
exportBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
// 导出图表
if (chart != null) {
doExport(chart);
} else {
JOptionPane.showMessageDialog(getParent(), "发生错误,请先生成图表!" + "", "数据导出", JOptionPane.ERROR_MESSAGE);
return;
}
}
});
innerPanel.add(exportBtn);
innerPanel.add(Box.createHorizontalGlue());
innerPanel.add(Box.createHorizontalGlue());
// , new GridBagConstraints(16, 1, 1, 1, 0, 0, GridBagConstraints.WEST,
// GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
chartParentPanel = new JPanel();
chartParentPanel.setLayout(new BorderLayout());
add(chartParentPanel, BorderLayout.CENTER);
}
/**
* 创建折线图
*
* @param type
* @return
*/
private ChartPanel createLineChart(int type) {
Date from = beginDate.getDate();
Date to = endDate.getDate();
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
chart = ChartFactory.createLineChart("结果统计图", "统计个数", "时间", dataset, PlotOrientation.VERTICAL, true, true,
true);
// if (type==0) {
Map<Object, Number> map = RiaModel.getInstance().statMaterialChecks(type, null, from, to,
(String) resultType.getSelectedItem(), codeType.getSelectedIndex());
for (Entry<Object, Number> entry : map.entrySet()) {
dataset.addValue(entry.getValue(), "数量", entry.getKey().toString());
}
// }
CustomRenderer.lineChartConfig(chart); // 折线图相关设置
ChartPanel chartPanel = new ChartPanel(chart, true);
return chartPanel;
}
private ChartPanel createBarChart(int type) {
Date from = beginDate.getDate();
Date to = endDate.getDate();
// 添加数据
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
// if (type==0) {
Map<Object, Number> map = RiaModel.getInstance().statMaterialChecks(type, null, from, to,
(String) resultType.getSelectedItem(), codeType.getSelectedIndex());
for (Entry<Object, Number> entry : map.entrySet()) {
// dataset.addValue(entry.getValue(), entry.getKey(),
// entry.getKey());
dataset.addValue(entry.getValue(), "数量", entry.getKey().toString());
}
chart = ChartFactory.createBarChart3D("结果统计图", "统计结果", // X轴的标签
"数量", // Y轴的标签
dataset, // 图标显示的数据集合
PlotOrientation.VERTICAL, // 图像的显示形式(水平或者垂直)
false, // 是否显示图例
true, // 是否生成提示的标签
false); // 是否生成URL链接
CustomRenderer.barChartConfig(chart);// 饼图相关设置
ChartPanel chartPanel = new ChartPanel(chart, true);
return chartPanel;
}
private ChartPanel createPieChart(int type) {
Date from = beginDate.getDate();
Date to = endDate.getDate();
// 添加数据
DefaultPieDataset dataset = new DefaultPieDataset();
// if (type==0) {
Map<Object, Number> map = RiaModel.getInstance().statMaterialChecks(type, null, from, to,
(String) resultType.getSelectedItem(), codeType.getSelectedIndex());
for (Entry<Object, Number> entry : map.entrySet()) {
dataset.setValue(entry.getKey().toString(), entry.getValue());
// dataset.setValue(entry.getValue().toString(),entry.getKey().getDay());
}
chart = ChartFactory.createPieChart("结果统计图", dataset, true, true, false);
CustomRenderer.pieChartConfig(chart);
ChartPanel chartPanel = new ChartPanel(chart, true);
return chartPanel;
}
/**
* 图表变更
*/
public void changeChart(int type) {
chartParentPanel.removeAll();
ChartPanel chartPanel = null;
switch (type) {
case 0: // bar
chartPanel = createBarChart(statType.getSelectedIndex());
break;
case 1:// pie
chartPanel = createPieChart(statType.getSelectedIndex());
break;
case 2:// line
chartPanel = createLineChart(statType.getSelectedIndex());
break;
}
if (chartPanel != null)
chartParentPanel.add(chartPanel);
}
public void dispose() {
}
/**
* 回调
*
* @param chartPanel
*/
private void doExport(JFreeChart chart) {
ExportReportDialog dialog = new ExportReportDialog(new ExportReportDialog.ExportAction() {
@Override
public void doExport(String path) {
try {
saveAsFile(chart, path, chartParentPanel.getWidth(), chartParentPanel.getHeight());
} catch (Exception e) {
log.error(e);
JOptionPane.showMessageDialog(getParent(), "发生错误,请确保文件可写!" + e.getMessage(), "数据导出",
JOptionPane.ERROR_MESSAGE);
}
}
@Override
public String getDefaultName() {
return "统计图-" + IRiaConsts.nameFormatter.format(new Date()) + ".PNG";
}
@Override
public FileNameExtensionFilter getFilter() {
return new FileNameExtensionFilter("PNG文件", new String[] { "png" });
}
});
dialog.setSize(400, 200);
int screenWidth = WidgetUtil.getScreenWidth() / 2; // 获取屏幕的宽
int screenHeight = WidgetUtil.getScreenHeight() / 2; // 获取屏幕的高
int height = dialog.getSize().height;
int width = dialog.getSize().width;
dialog.setLocation(screenWidth - width / 2, screenHeight - height / 2);
dialog.setVisible(true);
}
/**
* 保存图片
*
* @param chartPanel
* @param outputPath
* @param weight
* @param height
*/
public static void saveAsFile(JFreeChart chart, String outputPath, int weight, int height) {
FileOutputStream out = null;
try {
File outFile = new File(outputPath);
if (!outFile.getParentFile().exists()) {
outFile.getParentFile().mkdirs();
}
out = new FileOutputStream(outputPath);
// 保存为PNG
ChartUtilities.writeChartAsPNG(out, chart, weight, height);
Desktop.getDesktop().open(outFile); //打开图片
// 保存为JPEG
// ChartUtilities.writeChartAsJPEG(out, chartPanel, weight, height);
out.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) { // do nothing
}
}
}
}
}
以下是导出图片所用的对话框,代码如下:
package com.ringchi.ria.app.frames;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.apache.log4j.Logger;
import org.jdesktop.fuse.InjectedResource;
import org.jdesktop.fuse.ResourceInjector;
import com.ringchi.ria.app.IRiaConsts;
import com.ringchi.ria.app.core.RiaModel;
public class ExportReportDialog extends JDialog implements ActionListener {
private static Logger log = Logger.getLogger(ExportReportDialog.class);
@InjectedResource
private Font hintFont;
private JTextField path;
private JButton ok;
private JButton cancel;
private ExportAction action;
// private List<MaterialCheck> checks;
public static interface ExportAction {
public String getDefaultName();
public void doExport(String filename);
public FileNameExtensionFilter getFilter();
};
public ExportReportDialog(ExportAction action) {
super();
this.action = action;
ResourceInjector.get().inject(this);
this.setModal(true);
this.setTitle("数据导出");
SwingUtilities.invokeLater(new Runnable() {
public void run() {
init();
}
});
}
private void init() {
Container parent = getContentPane();
parent.setLayout(new GridBagLayout());
parent.add(Box.createRigidArea(new Dimension(10, 10)), new GridBagConstraints(0, 0, 1, 1, 0, 1,
GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
JLabel info = new JLabel("存放目录 ");
info.setHorizontalAlignment(SwingConstants.RIGHT);
info.setFont(hintFont);
path = new JTextField();
path.setFont(hintFont);
// path.setText(RiaModel.getInstance().getCache("export.path"));
JButton select = new JButton("选择");
select.setFont(hintFont);
select.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final JFileChooser dialog = new JFileChooser() {
public void approveSelection() {
File file = this.getSelectedFile();
if (file.isFile() && file.exists()) {
int copy = JOptionPane.showConfirmDialog(null, "文件已存在,确定要覆盖吗?", "保存",
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (copy == JOptionPane.YES_OPTION)
super.approveSelection();
} else
super.approveSelection();
}
};
//
dialog.setFileFilter(action.getFilter());
dialog.setDialogTitle("保存文件");
File last = new File(RiaModel.getInstance().getConfigValue(IRiaConsts.SAVE_DIR));
if (last.isFile())
last = last.getParentFile();
if (last.exists())
dialog.setCurrentDirectory(last);
dialog.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
last = dialog.getCurrentDirectory();
// final String theLast = "检测结果-" + IRiaConsts.nameFormatter.format(new Date()) + ".xlsx";
last = new File(last, action.getDefaultName());
dialog.setSelectedFile(last);
dialog.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent e) {
if (JFileChooser.DIRECTORY_CHANGED_PROPERTY.equals(e.getPropertyName())) {
dialog.setSelectedFile(new File(dialog.getSelectedFile(), action.getDefaultName()));
}
}
});
int result = dialog.showSaveDialog(getParent());
if (result == JFileChooser.APPROVE_OPTION) {
path.setText(dialog.getSelectedFile().getAbsolutePath());
}
}
});
parent.add(info, new GridBagConstraints(1, 1, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE,
new Insets(0, 0, 0, 0), 0, 0));
parent.add(path, new GridBagConstraints(2, 1, 2, 1, 1, 1, GridBagConstraints.EAST,
GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
parent.add(select, new GridBagConstraints(4, 1, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.NONE,
new Insets(0, 0, 0, 0), 0, 0));
ok = new JButton("导出");
ok.addActionListener(this);
ok.setFont(hintFont);
cancel = new JButton("取消");
cancel.addActionListener(this);
cancel.setFont(hintFont);
parent.add(cancel, new GridBagConstraints(2, 2, 1, 1, 1, 0, GridBagConstraints.EAST,
GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 10), 0, 0));
parent.add(ok, new GridBagConstraints(3, 2, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new Insets(0, 10, 0, 0), 0, 0));
parent.add(Box.createRigidArea(new Dimension(10, 10)), new GridBagConstraints(5, 3, 1, 1, 0, 1,
GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
}
public void actionPerformed(final ActionEvent e) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (e.getSource() == ok) {
doExport();
return;
}
if (e.getSource() == cancel) {
cancel();
}
}
});
}
public void doExport() {
String rpath = path.getText();
File test = new File(rpath);
if (test.isDirectory()) {
JOptionPane.showMessageDialog(this.getParent(), "请选择文件!", "数据导出", JOptionPane.ERROR_MESSAGE);
return;
}
try {
RiaModel.getInstance().setConfigValue(IRiaConsts.SAVE_DIR, rpath);
RiaModel.getInstance().getStore().save();
} catch (Exception e) {
}
action.doExport(rpath);
cancel();
}
public void cancel() {
this.setVisible(false);
this.dispose();
}
}