自从问世以来,Java 在多数方面都成长迅速。但一直以来,打印输出是Java 最弱的方面之一。事实上,Java1.0 根本不支持任何打印功能。Java1.1 在java.awt 包里包含了一个叫做PrintJob 的类,但是这个类提供的打印功能十分粗糙和不可靠。当 Java1.2 (或者说“Java2”)出现后,依据PrinterJob 以及在新的java.awt.print 包里定义的类和接口,它提供了一个彻底分离的打印设计机制(称为Java 2D printing API)。这些改进使得基于PrintJob的机制(即AWT printing)基本上被淘汰了,但是PrintJob 从未被真正废弃,而且至少在本文里仍然是一个技术上支持的类。
在J2SE 1.3 里又增加了一些变化,利用在java.awt 包里适合的JobAttributes 和PageAttributes 两个类,PrintJob 的功能扩展到设定任务和页面的属性。随着J2SE 1.3 的发布,打印能力变得足够强壮,但是在关联两个完全分离的打印机制时,仍然存在一些问题。比如,两种机制都使用java.awt.Graphics 类的一个实例,来展现打印内容,意味着所有要打印的东西都必须用一张图片表示。此外,更新后的PrintJob 工具变得更强壮,但仅提供了很有限的任务相关的属性设置。最终,两种机制都没有提供一种选择目标打印机的可编程的途径。
Java 打印最大的改变发生于J2SE 1.4 的发布,其带来的Java 打印服务API。第三代Java 打印支持的诞生,借助于javax.print 包的 PrintService 和DocPrintJob 接口的实现突破了上述限。因为新的API 代表了两种旧的打印机制功能定义的父集,是你应该通常使用的并是本文的焦点。
从较高层次上来看,使用Java 打印服务API 的步骤是很简单的:
1. 定位打印服务(打印机),可以限制返回的列表,只要那些符合您应用程序需要的打印机。打印服务由PrintService 的实例体现。
2. 通过调用PrintService 接口中定义的createPrintJob() 方法创建一个打印任务。打印任务由DocPrintJob 的一个实例代表。
3. 创建一个Doc 接口的实现,来描述你想要打印的数据。你也可以创建一个PrintRequestAttributeSet 的实例,来定义你想要的打印选项。
4. 通过DocPrintJob 接口定义的print() 方法来初始化打印,指定你先前创建的Doc,指定PrintRequestAttributeSet 或者空值。