java高级编程学习如何使用打印服务 API(三)

2014-11-24 02:59:55 · 作者: · 浏览: 3

而言之,OrientationRequested 是一个你用来将信息传递给打印机的属性,而
ColorSupported 是打印服务用来提供给你关于打印机能力信息的属性。你不能在创建打印
文档时把 ColorSupported 作为指定属性,因为打印机是否支持彩色打印是你的程序不能控
制的。

8.接口和实现

你第一次查看 javax.print.attribute 包里的接口和类时, 选择列表里的接口和类, 看起来
很令人困惑。 除了Attribute 和AttributeSet接口, 以及实现AttributeSet的HashAttributeSet
类,javax.print.attribute 包里有 4 个子接口和类,列出在表 4 和图 1 中。
Table 4. javax.print.attribute 里定义的接口和类

图-1,javax.print.attribute 包的一部分类的层次结构.

11
为什么你需要所有这些各式各样的接口和继承类呢,特别是已经有了 Attribute,
AttributeSet, 和 HashAttributeSet?是因为这些特殊的定制是为了确保在角色中使用合适
的有效属性。比方说,我提到过当你创建打印文档的位置,可以使用属性;但根据上下文,
一些属性,例如 ColorSupported 在那里不能使用。当创建这样的文档时,你可以使用
DocAttributeSet 接口(或者更明确一点,HashDocAttributeSet 这个实现) ,这个实现只允
许你添加继承 DocAttribute 这个接口的属性。这四种不同的角色如下:

Doc: 在创建打印文档时,描述文档如何打印
PrintJob: 从打印任务返回的属性,描述任务的状态
PrintRequest: 请求初始化打印时,传给任务的属性
PrintService: 由打印服务返回,用于描述打印机的能力

要知道这些如何工作, 我们来创建一个DocAttributeSet的实例, 然后尝试为AttributeSet
设置 DocAttributeSet 和 OrientationRequested 属性。HashDocAttributeSet 定义了一个无
参数的创建结构,所以你可以很容易地创建实例:

Do;
cAttributeSet attrs = new HashDocAttributeSet();

现在你已经创建了 AttributeSet,你可以调用 add()方法,并把 Attribute 的实现传递给
它。如果你看了 OrientationRequested 这个类的文档,你会发现它包含了一系列静态的
OrientationRequest 实例,每一个对应一种纸张打印方向,例如垂直人像或水平风景。要指
定你想要的方向,你所要做的只是利用 add()方法传递一个静态实例的引用:

DocAttributeSet attrs = new HashDocAttributeSet();

attrs.add(OrientationRequested.PORTRAIT);

ColorSupported 类有一点不同,但一样很简单,它定义了两种静态实例:一个表示支持
彩色打印, 另一个表示不支持。 你可以试着增加一个ColorSupported 属性到DocAttributeSet
去,代码如下:

DocAttributeSet attrs = new HashDocAttributeSet();

attrs.add(OrientationRequested.PORTRAIT);
12

attrs.add(ColorSupported.SUPPORTED);

如前所述,去指定是否支持彩色打印不恰当的,因为这不是程序所能控制的内容。换句
话说,ColorSupported 这个属性放到一系列文档属性上下文中并不合适,所以,运行先前
的代码,当添加 ColorSupported 属性时会抛出一个 ClassCastException 异常。

要这是如何工作的,记住每一个 AttributeSet 子接口(这个例子是 DocAttributeSet)都
有一个相应 Attribute 子接口(DocAttribute)和实现类(HashDocAttributeSet) 。当添加一
个属性时,实现子类试图把 Attribute 参数转换为相应的子接口类型,这样来确保只有当前
上下文合适的属性会添加成功。

这个例子中,HashDocAttributeSet 的 add()方法第一次调用,是配合一个
OrientationRequested 的实例,并成功将该对象转换为 DocAttribute。因为,如图 2 所示,
OrientationRequested 继承了那个接口。与之相反,传递 ColorSupported 实例的时候失败
了,因为其没有继承 DocAttribute。

图-2. javax.print.attribute 包的部分类层次图示。


这个例子举例表明,表 4 里的四个接口和类组确保了只有合适的属性在合适的上下文中
使用。 注意各种角色和不同的属性之间有大量的重叠部分, 所以很多属性与不止一个角色相
关联。例如,许多属性继承了 PrintJobAttribute 和 PrintRequestAttribute,因为大部分维
护和通过打印任务提供给你的属性, 与你可以在初始化打印时能指定的属性是相关的。 举例
来说,你可以通过添加名称到 PrintRequestAttributeSet 中来指定打印任务名,并且在打印
的时候,通过查询 PrintJobAttributeSet 来获得它。因此,JobName 属性类同时实现了
PrintRequestAttribute 和 PrintJobAttribute。
13
9.AttributeSet 和 HashAttributeSet

你已经知道了为什么会有四个子类,但是 AttributeSet 接口和 HashAttributeSet 父类又
是什么呢? AttributeSet / HashAttributeSet 在你不能确定要存储在这个集合中的属性仅仅
和一个角色相关时使用。记得我以前提到的 lookupPrintServices()方法允许你指定
AttributeSet 参数来限制返回的打印服务。 表面上看来最好指定 PrintServiceAttributeSet 的
实例,但是很多你可能用到的属性并不继承 PrintServiceAttribute。

我们假设你想要让 lookupPrintServices() 方法返回, 支持彩色打印和水平方向打印的打
印机。这些属性与 ColorSupported 和 OrientationRequested 属性关联,但请注意这些类并
不共享角色:前者是一个 PrintServiceAttribute,而 OrientationRequested 与另外三个角色
(Doc,PrintRequest 和 PrintJob)关联,如图-2 所示。这意味着不存在单个特定角色的
AttributeSet 接口或类来同时包含 ColorSupported 和 Sides 属性。

创建一个 AttributeSet,并使其同时包含 OrientationRequested 和 ColorSupported 实例
的简单方