javax.print.attribute

javax.print.attribute

軟體包javax.print.attribute提供了描述JavaTM Print Service屬性的類型以及如何分類這些屬性的類和接口。javax.print.attribute 包中包括了作為屬性集接口具體實現的HashAttributeSet。DocAttribute指定每個文檔的特徵和套用到每個文檔的列印作業設定。屬性包括PrintRequestAttribute(定套用到整個列印作業和列印作業中所有文檔的設定);PrintJobAttribute(報告列印作業的狀態);PrintServiceAttribute(報告列印服務的狀態);SupportedValuesAttribute(為另一個屬性提供支持的值)。

屬性,簡介,屬性類別和值,屬性職責,屬性集,屬性類設計,屬性供應商,使用屬性,套用,

屬性

簡介

設定列印作業時,客戶端會指定兩件事情:列印數據和處理指令。列印數據是要列印的實際內容。處理指令告知列印機如何列印該列印數據,如:使用什麼介質,列印多少副本,在紙上是單面列印還是雙面列印。客戶端使用 Java Print Service API 的屬性定義來指定這些處理指令。
列印數據和處理指令都是獨立的實體。這意味著:您可以在不同時間使用不同的處理指令列印同一列印數據。
例如,您可以在美國信函大小的白紙上雙面、裝訂列印 20 張幻燈片演示文稿副本作為演講的講義;還可以在美國信函大小的透明介質上單面列印一份相同的幻燈片演示文稿作為演講的實際幻燈片。
您可以在不同時間使用相同的處理指令列印不同的數據。例如,您可以將默認處理指令設定為:美國信函大小的紙張、雙面、裝訂。每當列印一項作業時,會使用這些設定進行列印,除非顯式重寫它們。
處理指令不指定列印作業處理該請求的方式;每條處理指令僅是對列印作業結果的描述。列印作業確定實現處理指令所指定結果的方式。將處理指令表示為描述項可為實現列印作業提供更大的靈活性。

屬性類別和值

每個列印機都有一組功能,如在不同大小的紙張上列印或列印多個副本。每個功能都有一個範圍值。例如,列印機的方向功能可能有以下範圍值:[landscape, portrait]。對於每個列印請求,可以將該功能設定為這些值之一。Java Print Service API 使用術語屬性類別指列印機功能,使用術語屬性值指該功能的值。
在 Java Print Service API 中,通過實現 Attribute 接口的 Java 類來表示屬性類別。屬性值是這樣的類或其某個子類的實例。例如,要指定副本數,應用程式會構造一個具有所需副本數的 Copies 類的實例,並將 Copies 實例用作列印請求的一部分。在這種情況下,Copies 類表示屬性類別,Copies 實例表示屬性值。

屬性職責

列印作業提交給印表機時,客戶端將提供描述列印數據特徵的屬性(如,文檔名稱),以及應如何列印列印數據(如,雙面、五份)。如果列印作業由多部分列印數據組成,則不同部分可能具有不同的處理指令,如將 8 × 11 英寸的介質用於第一個文檔,11 × 17 英寸的介質用於另一個文檔。
列印機開始處理列印作業之後,關於該作業的其他信息將可供使用,可能包括:作業狀態(如完成 或排隊)和到目前為止已列印的頁數。這些信息片段也是屬性。屬性還可描述列印機本身,如:印表機名稱、印表機位置和已排隊的作業數。
Java Print Service API 使用 Attribute 的五個子接口定義這些不同類型的屬性:
DocAttribute 指定每個文檔的特徵和套用到每個文檔的列印作業設定。
PrintRequestAttribute 指定套用到整個列印作業和列印作業中所有文檔的設定。
PrintJobAttribute 報告列印作業的狀態。
PrintServiceAttribute 報告列印服務的狀態。
SupportedValuesAttribute 為另一個屬性提供支持的值。
每個屬性類實現一個或多個這些標記子接口,以指示在 API 中可以使用該屬性的位置。如果屬性類實現多個標記子接口,則可以在多個上下文中使用該屬性。例如,介質屬性可以作為 DocAttribute 套用到列印作業中的一個文檔,或作為 PrintRequestAttribute 套用到整個列印作業。某些低級別屬性從不用於其自身,但是,總是可以將它們匯集到高級別屬性中。這此低級別屬性類僅實現接口 Attribute,不能實現任何標記子接口
Java Print Service API 定義了一組標準屬性類,它可以按照 Internet Printing Protocol (IPP) 版本 1.1 對屬性進行建模。標準屬性類位於子包 javax.print.attribute.standard 中,目的是保持實際屬性類在概念上與包 javax.print.attribute 中定義的一般設備分開。

屬性集

在提交列印作業時,客戶端通常需要提供多個處理指令。例如,客戶端可能需要指定大小為 A4 的介質和橫向方向。要傳送多個處理指令,客戶端將屬性收集到 Java Print Service API 通過 AttributeSet 接口所表示的屬性集中。
AttributeSet 接口類似於 Map 接口:它提供鍵到值的映射,其中每個鍵都是惟一的,並且只能包含一個值。但是,AttributeSet 接口設計用於專門支持 Java Print Service API 的需求。AttributeSet 要求:
AttributeSet 中的每個鍵對應於一個類別,鍵的值只能是屬性值之一,它屬於該鍵表示的類別。因此,與 Map 不同,AttributeSet 限制了鍵的可能值:不能將屬性類別設定為不屬於該類別的屬性值。
在同一集合中,不能存在同一類別的兩個屬性。例如,屬性集合決不能同時包含“單面”屬性和“雙面”屬性,因為這兩個屬性會導致列印機指令衝突。
只可以將實現 Attribute 接口的屬性添加到該集合。
javax.print.attribute 包中包括了作為屬性集接口具體實現的 HashAttributeSet。HashAttributeSet 提供基於哈希映射的屬性集。您可以使用此實現,或提供自己的接口 AttributeSet 實現。
Java Print Service API 提供屬性集的四個規範,它們限於僅包含四種屬性之一,如屬性職責一節所討論的:
DocAttributeSet
PrintRequestAttributeSet
PrintJobAttributeSet
PrintServiceAttributeSet
注意,這裡僅列出了四種屬性集,但是有五種屬性。接口 SupportedValuesAttribute 表示為另一個屬性提供支持值的屬性。永遠不可能將支持值屬性匯集到屬性集中,因此不存在為它們定義的屬性集子接口。
在某些上下文中,屬性集是唯讀的,這意味著只允許客戶端檢查屬性集的內容,但不能更改它們。在其他上下文中,屬性集是可讀寫的,這意味著允許客戶端檢查和更改屬性集的內容。對於唯讀屬性集,調用更改操作會拋出 UnmodifiableSetException。
包 javax.print.attribute 包括每個屬性集子接口的一個具體實現:
HashDocAttributeSet
HashPrintRequestAttributeSet,
HashPrintJobAttributeSet,
HashPrintServiceAttributeSet.
所有這些類都擴展 HashAttributeSet,並強制要求只允許屬性集包含相應類型屬性的限制。

屬性類設計

屬性值是一個小的原子數據項,如整數或枚舉值。Java Print Service API 不使用基本數據類型(如 int)來表示屬性值,原因如下:
基本數據類型不是類型安全的。例如,編譯器不應允許將“copies”屬性值用於“sides”屬性。
一些屬性必須表示為幾個值的記錄。列印機解析度就是一個例子,它需要兩個數(如,表示 600 × 300 dpi 的 600 和 300)。
對於類型安全性和要統一表示所有屬性,Java Print Service API 將每個屬性類別定義為類,如類 Copies、類 Sides 和 類 PrinterResolution。每個屬性類可以包裝一個或多個包含屬性值的基本數據項。屬性集操作在添加屬性、在同一類別中查找現有屬性和查找給定其類別的屬性時經常執行屬性類別對象之間的比較。因為屬性類別由類表示,所以使用 Class.equals 方法可以執行快速的屬性值比較。
儘管 Java Print Service API 包括大量不同的屬性類別,但是僅存在很少的不同類型的屬性值。大多數屬性可由少量數據類型表示,如:整數值、整數範圍、文本或整數值的枚舉。類別接受的屬性值類型稱為屬性的抽象語法。為了提供一致性並減少代碼重複,Java Print Service API 定義了抽象語法類,以表示每個抽象語法,並且只要可能,可以將這些類用作標準屬性的父級。抽象語法類是:
EnumSyntax 提供類型安全的枚舉,其中枚舉值表示為單個對象。每個枚舉都是包裝隱藏 int 值的枚舉類實例。
IntegerSyntax 是用於整數值屬性的抽象語法
TextSyntax 是用於文本值屬性的抽象語法,並且包括立提供文本字元串的自然語言的語言環境。
SetOfIntegerSyntax 是表示整數範圍或整數集的屬性的抽象語法
ResolutionSyntax 是表示解析度值(如 600×300 dpi)的屬性的抽象語法
Size2DSyntax 是表示二維大小(如,紙張大小為 8.5 × 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.class。getCategory 方法最終確保了標準屬性類的所有供應商定義的子類都顯示在同一類別中。每個屬性對象在構造之後都是不可變的,這樣可以隨意地傳遞屬性對象引用。要獲取不同的屬性值,請構造不同的屬性對象。

屬性供應商

Java Print Service API 被設計成可讓供應商:
javax.print.attribute.standard 中定義的所有標準屬性定義新的特定於供應商的值。
定義表示供應商列印機專用功能(標準屬性已不支持)的新屬性類別。
要為屬性定義一個新值,客戶端可以使用任意值在運行時構造此屬性的實例。但是,使用 EnumSyntax 的抽象語法類的枚舉屬性在編譯時將所有的可能屬性值指定為屬性類的單個實例。這意味著在運行時無法構造新的枚舉值。要為標準枚舉屬性定義新的特定於供應商的值,供應商必須定義一個指定單個新實例的新屬性類。要確保新的屬性值與標準屬性值在相同的類別中,新的屬性類必須是標準屬性類的子類。
要定義新的屬性類別,供應商需要定義新的屬性類。此屬性類(與標準屬性類類似)實現 Attribute 或其子接口之一,並擴展抽象語法類。供應商可以使用現有的抽象語法類,或者定義新的抽象語法類。無論在哪裡(如在 AttributeSet 中)使用 Attribute,都可以使用供應商定義的新屬性。

使用屬性

典型的列印應用程式使用 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 引用具有有意義的解釋時,方法的 null 引用參數才是正確的。與之相反的用法是不正確的編碼,可能立即或在稍後某一時間導致運行時異常。

套用

IllegalArgumentException 和 NullPointerException 是針對這種情況的典型的、可接受的運行時異常的示例。
從以下版本開始:
1.4

相關詞條

熱門詞條

聯絡我們