Google Hack、Perl Hack、CSS Hack,最近Hack一词使用频率颇高,声名鹊起,成为了时髦词汇,Hack(骇客)一词很早就有,曾经还有过坏名声,不过此Hack非彼Hack,用于软件中则大概是说快速而聪明的解决问题方式,引申的讲就是因为能够深入研究而参透某事物,从而获得的一种“投机取巧”的手段。赶一下时髦,刚好最近需要开发的测试工具中需要用到几个个开源项目,有些内容似乎需要自己手工Hack。由于篇幅所限,这里先举一个最简单的例子吧,以我们常用的JFreeChart这一图表生成工具为例,我们有时需要将图表放在PDF中,成为漂亮的文档,该如何解决呢?标准的JFreeChart库并不提供这些方法,那么只能自己Hack了。这里使用iText这一开源库做为PDF的生成工具,首先需要对iText中将图像加入到PDF的方法做个了解,在iText中对图像的处理有赖于com.lowagie.text.Image这个类,通过Image.getInstance(PdfContentByte cb, java.awt.Image awtImage, float quality)方法来构造Image的实例,然后通过Document.add(Image)将图像加入到PDF文档中。接下来就是想办法将Image.getInstance()能够与JFreeChart对接。以Swing/Applet形式展现的JFreeChart图表,提供鼠标右键事件的支持,其中鼠标右键菜单中包含将图表保存为png格式图片的选型,那么就以此为入口,实现所谓的Hack。首先在JFreeChart的源代码中找到ChartPanel这个类的doSaveAs()方法,其内容如下:
public void doSaveAs() throws IOException {
JFileChooser fileChooser = new JFileChooser();
......
ChartUtilities.saveChartAsPNG(new File(filename), this.chart, getWidth(), getHeight());
}
找到ChartUtilities中的saveChartAsPNG()方法,该方法实际调用的是同一类中的writeChartAsPNG()方法,因此就以此方法中的代码为参考,了解其PNG或JPEG格式图片生成的机理,该方法中提供了一个重要的线索,如下: java.awt.image.BufferedImage bufferedImage = chart.createBufferedImage(width, height, info); 而BufferedImage正是java.awt.Image的子类,这个bufferedImage正是我们用来将iText来接JFreeChart的桥梁,通过BufferedImage来构造iText的Image,最终代码如下:
void printChartToPDF(JFreeChart chart, int width, int height, String fileName) {
Document document = new Document(PageSize.A4);
try {
PdfWriter pdf = PdfWriter.getInstance(document, new FileOutputStream(fileName + ".pdf"));
document.open();
document.addAuthor("tigerwf");
document.add(new Paragraph("The test result is as below:"));
PdfContentByte contentByte = pdf.getDirectContent();
int margin = 150;
height = (int)(height * (PageSize.A4.width()- margin) / width);
width = (int)PageSize.A4.width() - margin;
Image png = Image.getInstance(contentByte, chart.createBufferedImage(width, height), 1);
png.setAlignment(Image.MIDDLE);
document.add(png);
} catch (Exception ex) {
ex.printStackTrace();
}
document.close();
}
此外还可以参考ChartUtilities类中的writeScaledChartAsPNG方法,来修改以上代码,根据自己的实际需要对尺寸进行调整,实现更好的文档显示效果。至此,Hack过程完成。
这里仅仅是一个简单的实例,将两个开源项目桥接起来,实现我们所要的功能。但如果把这种思想它拓展开来,在参透源代码的基础上够增加更多的实用功能,并将其贡献于开源社区,这便真正的找到Open Source的精神,会真正体会到开源的乐趣。