Module java.desktop

Package javax.print.attribute


package javax.print.attribute
提供描述Java打印服务属性类型及如何将其收集到属性集中的类和接口。

什么是属性?

在设置打印作业时,客户端需要指定两个内容:打印数据处理指令。打印数据是实际要打印的内容。处理指令告诉打印机如何打印打印数据,例如:使用何种介质、打印多少份、是否单双面打印等。客户端使用Java打印服务API的属性定义来指定这些处理指令。

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

  • 您可以在不同时间使用不同的处理指令打印相同的打印数据。
    例如,您可以在美国信纸大小的白纸上打印幻灯片演示,双面打印,装订,打印20份作为演讲手册;您也可以在美国信纸大小的透明纸上打印相同的幻灯片演示,单面打印,打印一份作为演讲的实际幻灯片。
  • 您可以在不同时间使用相同的处理指令打印不同的数据。例如,您可以将默认处理指令设置为:美国信纸大小的纸张,双面打印,装订。每次打印作业时,除非您明确覆盖,否则将使用这些设置进行打印。
处理指令不指定打印作业如何处理请求;每个处理指令只是打印作业结果的描述。打印作业决定实现处理指令指定的结果的方式。将处理指令表示为描述性项提供了更多实现打印作业灵活性。

属性类别和值

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

在Java打印服务API中,属性类别由实现Attribute接口的Java类表示。属性值是这样一个类的实例或其子类之一。例如,为了指定打印份数,应用程序构造一个带有所需份数的Copies类的实例,并将该Copies实例作为打印请求的一部分。在这种情况下,Copies类表示属性类别,Copies实例表示属性值。

属性角色

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

一旦打印机开始处理打印作业,有关作业的附加信息变得可用,这些信息可能包括:作业状态(如已完成排队)和迄今为止打印的页数。这些信息也是属性。属性还可以描述打印机本身,例如:打印机名称,打印机位置和排队作业数。

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

每个属性类都实现了这些标记子接口中的一个或多个,以指示属性在API中的使用位置。如果属性类实现了多个标记子接口,则属性可以在多个上下文中使用。例如,介质属性可以作为DocAttribute应用于打印作业中的一个文档,也可以作为PrintRequestAttribute应用于整个打印作业。某些低级属性永远不会单独使用,而是始终聚合到更高级别的属性中。这些低级属性类只实现接口Attribute,而不实现任何标记子接口。

Java打印服务API定义了一组标准属性类,这些类是基于Internet打印协议(IPP)版本1.1中的属性模型。标准属性类位于子包javax.print.attribute.standard中,以将实际属性类在概念上与包javax.print.attribute中定义的通用设备分开。

属性集

客户端通常在提交打印作业时需要提供多个处理指令。例如,客户端可能需要指定A4纸张大小和横向方向。为了发送多个处理指令,客户端将属性收集到一个属性集中,Java打印服务API使用AttributeSet接口表示这个属性集。

AttributeSet接口类似于Map接口:它提供了一个键到值的映射,其中每个键是唯一的,并且最多只能包含一个值。但是,AttributeSet接口专门设计用于支持Java打印服务API的需求。一个AttributeSet要求:

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

Java打印服务API提供了四种属性集的特化,这些属性集被限制为仅包含四种属性中的一种,如在属性角色部分讨论的:

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

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

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

所有这些类都扩展自HashAttributeSet,并强制执行属性集只能包含相应类型属性的限制。

属性类设计

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

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

  • EnumSyntax 提供了一种类型安全的枚举,其中枚举值被表示为单例对象。每个枚举单例是枚举类的实例,包装了一个隐藏的int值。
  • IntegerSyntax 是整数值属性的抽象语法。
  • TextSyntax 是文本值属性的抽象语法,并包括给出文本字符串自然语言的区域设置。
  • 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方法提供实现,该方法返回属性类别。对于SidesgetCategory方法返回Sides.class。为了确保任何供应商定义的标准属性类的子类出现在相同类别中,getCategory方法是final的。一旦构造完成,每个属性对象都是不可变的,以便可以自由传递属性对象引用。要获取不同的属性值,构造一个不同的属性对象。

属性供应商

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;
 }
 //设置文档类型。有关更多信息,请参阅DocFlavor文档
 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引用参数具有有意义的解释,否则将null引用参数传递给方法是不正确的。相反的用法是不正确的编码,可能会导致立即或以后的某个时间发生运行时异常。例如,IllegalArgumentExceptionNullPointerException是这类情况下的典型且可接受的运行时异常。

自从:
1.4
  • Class
    Description
    接口Attribute是由任何打印属性类实现的基本接口,表示该类代表一个打印属性。
    接口AttributeSet指定了一组打印属性的接口。
    AttributeSetUtilities提供了用于操作AttributeSets的静态方法。
    DateTimeSyntax是一个抽象基类,提供了所有值为日期和时间的属性的通用实现。
    接口DocAttribute是一个标记接口,打印属性类实现该接口以指示该属性表示文档的设置。
    接口DocAttributeSet指定了一组文档属性的接口,即实现接口DocAttribute的打印属性。
    EnumSyntax是一个抽象基类,提供了所有“类型安全枚举”对象的通用实现。
    HashAttributeSet提供了具有哈希映射特性的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)的属性的通用实现。