模块 java.desktop

包 javax.print.attribute


javax.print.attribute
提供描述 Java Print Service 属性类型以及如何将它们收集到属性集中的类和接口。

什么是属性?

设置打印作业时,客户端指定两件事:打印数据处理指令。打印数据是实际要打印的内容。处理指令告诉打印机如何打印打印数据,例如:使用什么介质,打印多少份,是单面打印还是双面打印。客户端使用 Java Print Service API 的属性定义指定这些处理指令。

打印数据和处理指令是独立的实体。这意味着:

  • 您可以使用不同的处理指令在不同的时间打印相同的打印数据。
    例如,您可以在 US letter 大小的白纸上打印幻灯片演示文稿,双面装订,20 份作为演讲讲义;您可以在美国信纸大小的透明胶片上打印相同的幻灯片演示文稿,单面,一份副本以制作演讲的实际幻灯片。
  • 您可以在不同的时间使用相同的处理指令来打印不同的数据。例如,您可以将默认处理指令设置为:美国信纸尺寸的纸张,双面,装订。每当您打印作业时,它都会使用这些设置进行打印,除非您明确重写它们。
处理指令没有指定打印作业如何处理请求;每条处理指令只是对打印作业结果的描述。打印作业决定了它实现处理指令指定结果的方式。将处理指令表示为描述性项目为实现打印作业提供了更大的灵活性。

属性类别和值

每台打印机都有一组功能,例如在不同纸张尺寸上打印的能力或打印多份副本的能力。每个功能都有一个值范围。例如,打印机的方向功能可能具有以下值范围:[landscape, portrait]。对于每个打印请求,功能都设置为这些值之一。 Java 打印服务 API 使用术语属性类别指打印机功能和术语属性值指的是能力的值。

在 Java Print Service API 中,属性类别由实现 Attribute 接口的 Java 类表示。属性值是此类或其子类之一的实例。例如,要指定份数,应用程序会使用所需份数构造 Copies 类的实例,并将 Copies 实例用作打印请求的一部分。在本例中,Copies类表示属性类别,Copies实例表示属性值。

属性角色

当向打印机提交打印作业时,客户端提供描述打印数据特征的属性,例如文档名称,以及打印数据应该如何打印,例如双面,五份。如果打印作业包含多份打印数据,则不同的部分可能有不同的处理指令,例如第一个文档使用 8 x 11 英寸介质,另一个文档使用 11 x 17 英寸介质。

打印机开始处理打印作业后,有关该作业的其他信息将可用,其中可能包括:作业状态(例如completed或者排队) 和目前打印的页数。这些信息也是属性。属性还可以描述打印机本身,例如:打印机名称、打印机位置和排队的作业数。

Java 打印服务 API 使用 Attribute 的五个子接口定义了这些不同类型的属性:

每个属性类都实现一个或多个这些标记子接口,以指示可以在 API 中的何处使用该属性。如果一个属性类实现了多个标记子接口,则该属性可以在多个上下文中使用。例如,媒体属性可以作为 DocAttribute 应用于打印作业中的一个文档,也可以作为 PrintRequestAttribute 应用于整个打印作业。某些低级属性从不单独使用,但总是聚合到更高级别的属性中。这些低级属性类仅实现接口 Attribute ,而不是任何标记子接口。

Java Print Service API 定义了一组标准属性类,它们以 Internet 打印协议 (IPP) 1.1 版中的属性为模型。标准属性类位于子包 javax.print.attribute.standard 中,以使实际属性类在概念上与包 javax.print.attribute 中定义的通用设备分开。

属性集

客户端在提交打印作业时通常需要提供多个处理指令。例如,客户端可能需要指定 A4 的介质尺寸和横向。为了发送多个处理指令,客户端将属性收集到一个属性集中,Java Print Service API 用AttributeSet接口表示。

AttributeSet 接口类似于 Map 接口:它提供键到值的映射,其中每个键都是唯一的,并且只能包含一个值。但是,AttributeSet 接口专门用于支持 Java Print Service API 的需求。 AttributeSet 要求:

  1. AttributeSet中的每个键对应一个类别,键的值只能是属于该键代表的类别的属性值之一。因此,与 Map 不同,AttributeSet 限制了键的可能值:属性类别不能设置为不属于该类别的属性值。
  2. 同一组中不能存在来自同一类别的两个属性。例如,一个属性集合不能同时包含“单面”属性和“双面”属性,因为这两个属性给打印机的指令是相互冲突的。
  3. 只有实现 Attribute 接口的属性才能添加到集合中。
javax.print.attribute 包包括 HashAttributeSet 作为属性集接口的具体实现。 HashAttributeSet 提供基于hash map的属性集。您可以使用此实现或提供您自己的接口 AttributeSet 实现。

Java Print Service API 提供了一个属性集的四个特化,这些属性集被限制为仅包含四种属性中的一种,如 属性角色 部分中所讨论的:

请注意,这里只列出了四种属性集,但有五种属性。接口 SupportedValuesAttribute 表示为另一个属性提供支持值的属性。支持值属性永远不会聚合到属性集中,因此没有为它们定义的属性集子接口。

在某些情况下,属性集是只读的,这意味着客户端只能检查属性集的内容而不能更改它们。在其他情况下,属性集是可读写的,这意味着允许客户端检查和更改属性集的内容。对于只读属性集,调用变异操作会抛出 UnmodifiableSetException

javax.print.attribute 包括每个属性集子接口的一个具体实现:

所有这些类都扩展了 HashAttributeSet 并强制限制属性集只允许包含相应种类的属性。

属性类设计

属性值是一个小的原子数据项,例如整数或枚举值。 Java 打印服务 API 不使用原始数据类型(例如 int)来表示属性值,原因如下:
  • 原始数据类型不是类型安全的。例如,编译器不应允许将“copies”属性值用于“sides”属性。
  • 某些属性必须表示为多个值的记录。一个示例是打印机分辨率,它需要两个数字,例如 600 和 300 代表 600 x 300 dpi。
为了类型安全和统一表示所有属性,Java Print Service API 将每个属性类别定义为一个类,例如类 Copies 、类 Sides 和类 PrinterResolution 。每个属性类都包含一个或多个包含属性值的原始数据项。属性集操作在添加属性时执行属性类别对象之间的频繁比较,查找同一类别中的现有属性,以及查找给定类别的属性。因为属性类别由类表示,所以可以使用 Class.equals 方法执行快速属性值比较。

尽管 Java Print Service API 包含大量不同的属性类别,但只有几种不同类型的属性值。大多数属性可以用少量数据类型表示,例如:整数值、整数范围、文本或整数值的枚举。类别接受的属性值的类型称为属性的抽象语法。为了提供一致性并减少代码重复,Java Print Service API 定义了抽象语法类来表示每个抽象语法,并且这些类尽可能用作标准属性的父级。抽象语法类是:

  • EnumSyntax 提供类型安全的枚举,其中枚举值表示为单例对象。每个枚举单例都是枚举类的一个实例,它包装了一个隐藏的 int 值。
  • IntegerSyntax 是整数值属性的抽象语法。
  • TextSyntax 是文本值属性的抽象语法,包括一个提供文本字符串自然语言的locale。
  • SetOfIntegerSyntax 是表示一个范围或一组整数的属性的抽象语法
  • ResolutionSyntax 是表示分辨率值(例如 600x300 dpi)的属性的抽象语法。
  • Size2DSyntax 是表示二维尺寸的属性的抽象语法,例如 8.5 x 11 英寸的纸张尺寸。
  • DateTimeSyntax 是值为日期和时间的属性的抽象语法。
  • URISyntax 是其值为统一资源指示符的属性的抽象语法。
抽象语法类独立于使用它们的属性。事实上,与打印无关的应用程序可以使用抽象语法类。尽管大多数标准属性类都扩展了抽象语法类之一,但是扩展这些类之一不需要属性类。抽象语法类仅仅提供了一个方便的实现,可以被许多属性类共享。

每个属性类直接或间接实现Attribute接口,以将其标记为打印属性。在某些上下文中可以出现在受限属性集中的属性类也实现了 Attribute 的一个或多个子接口。大多数属性类还扩展了适当的抽象语法类以获得实现。考虑 Sides 属性类:


 public class Sides
   extends EnumSyntax
   implements DocAttribute, PrintRequestAttribute, PrintJobAttribute
 {
   public final Object getCategory()
   {
     return Sides.class;
   }
 ...
 } 
 

由于每个属性类都实现了 Attribute ,因此每个属性类都必须为 getCategory 方法提供一个实现,该方法返回属性类别。在 Sides 的情况下, getCategory 方法返回 Sides.classgetCategory 方法是最终的,以确保标准属性类的任何供应商定义的子类出现在同一类别中。每个属性对象在构建后都是不可变的,因此可以自由传递属性对象引用。要获取不同的属性值,请构造不同的属性对象。

属性供应商

Java 打印服务 API 旨在让供应商能够:
  • javax.print.attribute.standard 中定义的任何标准属性定义新的特定于供应商的值。
  • 定义新的属性类别,表示标准属性尚未支持的供应商打印机的专有功能。
要为属性定义新值,客户端可以在运行时构造具有任意值的此类属性的实例。但是,使用抽象语法类 EnumSyntax 的枚举属性在编译时将所有可能的属性值指定为属性类的单例实例。这意味着不能在运行时构造新的枚举值。要为标准枚举属性定义新的特定于供应商的值,供应商必须定义一个新的属性类来指定新的单例实例。为确保新属性值与标准属性值属于同一类别,新属性类必须是标准属性类的子类。

要定义一个新的属性类别,供应商定义一个新的属性类。该属性类与标准属性类一样,实现了Attribute或其子接口之一,并扩展了一个抽象语法类。供应商可以使用现有的抽象语法类或定义一个新的。可以在使用 Attribute 的任何地方使用新的供应商定义的属性,例如在 AttributeSet 中。

使用属性

典型的打印应用程序使用PrintRequestAttributeSet,因为打印请求属性是客户端通常指定的属性类型。此示例演示创建打印请求属性的属性集并根据指定的属性定位可以打印文档的打印机:

 FileInputStream psStream;
 try {
   psstream = new FileInputStream("file.ps");
 } catch (FileNotFoundException ffne) {
 }
 if (psstream == null) {
   return;
 }
 //Set the document type. See the DocFlavor documentation for
 //more information.
 DocFlavor psInFormat = DocFlavor.INPUT_STREAM.POSTSCRIPT;
 Doc myDoc = new SimpleDoc(pstream, psInFormat, null);
 PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
 aset.add(new Copies(5));
 aset.add(MediaSize.A4);
 aset.add(Sides.DUPLEX);
 PrintService[] services =
   PrintServiceLookup.lookupPrintServices(psInFormat, aset);
 if (services.length > 0) {
   DocPrintJob job = services[0].createPrintJob();
   try {
     job.print(myDoc, aset);
   } catch (PrintException pe) {}
 }
  

请注意:在 javax.print API 中,方法的 null 引用参数是不正确的,除非在方法上明确记录为具有有意义的解释。相反的用法是不正确的编码,可能会立即或稍后导致运行时异常。 IllegalArgumentExceptionNullPointerException 是此类情况下典型且可接受的运行时异常的示例。

自从:
1.4
  • 描述
    接口 Attribute 是任何和每个打印属性类实现的基本接口,用于指示该类表示打印属性。
    Interface AttributeSet 指定一组打印属性的接口。
    AttributeSetUtilities 提供用于操作 AttributeSets 的静态方法。
    DateTimeSyntax 类是一个抽象基类,提供所有值为日期和时间的属性的通用实现。
    接口 DocAttribute 是打印属性类实现的标记接口,用于指示该属性表示文档的设置。
    接口 DocAttributeSet 指定一组文档属性的接口,即实现接口 DocAttribute 的打印属性。
    EnumSyntax 是一个抽象基类,提供所有“类型安全枚举”对象的通用实现。
    HashAttributeSet 提供具有hash map特征的 AttributeSet 实现。
    HashDocAttributeSet 提供了一个属性集,它继承了类 HashAttributeSet 的实现,并强制执行接口 DocAttributeSet 的语义限制。
    HashPrintJobAttributeSet 提供了一个属性集,它继承了类 HashAttributeSet 的实现,并强制执行接口 PrintJobAttributeSet 的语义限制。
    HashPrintRequestAttributeSet 从类 HashAttributeSet 继承其实现,并强制执行接口 PrintRequestAttributeSet 的语义限制。
    HashPrintServiceAttributeSet 提供了一个属性集,它继承了类 HashAttributeSet 的实现,并强制执行接口 PrintServiceAttributeSet 的语义限制。
    IntegerSyntax 是一个抽象基类,提供所有具有整数值的属性的通用实现。
    PrintJobAttribute 是打印属性类实现的标记接口,用于指示属性描述打印作业的状态或打印作业的某些其他特征。
    接口PrintJobAttributeSet 指定一组打印作业属性的接口,即实现接口PrintJobAttribute 的打印属性。
    接口 PrintRequestAttribute 是打印属性类实现的标记接口,用于指示属性表示打印作业的请求设置。
    接口PrintRequestAttributeSet 指定一组打印请求属性的接口,即实现接口PrintRequestAttribute 的打印属性。
    接口 PrintServiceAttribute 是打印属性类实现的标记接口,用于指示属性描述打印服务的状态或打印服务的某些其他特征。
    接口PrintServiceAttributeSet 指定一组打印作业属性的接口,即实现接口PrintServiceAttribute 的打印属性。
    ResolutionSyntax 是一个抽象基类,提供表示打印机分辨率的所有属性的通用实现。
    SetOfIntegerSyntax 是一个抽象基类,提供所有属性的通用实现,其值为一组非负整数。
    Size2DSyntax 是一个抽象基类,提供所有表示二维大小的属性的通用实现。
    接口 SupportedValuesAttribute 是一个标记接口,打印属性类实现该接口以指示该属性描述了另一个属性的支持值。
    TextSyntax 是一个抽象基类,提供所有值为字符串的属性的通用实现。
    抛出以指示无法执行请求的操作,因为集合不可修改。
    URISyntax 是一个抽象基类,提供所有属性的通用实现,其值为统一资源标识符 (URI)。