選擇正確的打印機 還記得我們在開始關於討論DocFlavor之前關於打印機的那個精確支持你想要打印的數據類型的假設嗎?這似乎看起來沒有必要
實際上
你會對給你的打印機所支持的文檔類型感到吃驚
例如
剛提到文本類型看起來似乎是最容易支持的
所以
如果你的程序要打印一個普通文本或者HTML文本
你可以隨便選擇一個打印服務並把它送到打印機那去
然而大部分打印機不支持基於文本的表現類
如果你試圖向打印機發送它不支持的DocFlavor
會產生下面的異常
Exception in thread
main
sun
print
PrintJobFlavorException: invalid flavor at sun
print
Win
PrintJob
print(Win
PrintJob
java:
) at PrintTest
main(PrintTest
java:
)
現在你已經知道了如何得到一個DocFlavor的引用而且我們也討論了選擇支持這個flavor的打印機重要性
接下來我來告訴你如何確定你使用的打印機支持它
我先前說過lookupPrintServices()允許你指定一個DocFlavor作為第一個參數
如果你指定的參數非空
那麼方法會返回相應支持這個的打印機的實例
例如以下代碼將返回可以通過URL來打印gif文件的打印機的列表
DocFlavor flavor = DocFlavor
URL
GIF;
PrintService[] services = PrintServiceLookup
lookupPrintServices(flavor
null);
另外
如果你的程序已經獲得了打印服務的實例
而你想知道它是否支持另一種特定的flavor
你可以調用isDocFlavorSupported()方法
在下面的代碼裡
將得到一個默認打印機的引用
如果不能打印gif就會出現錯誤信息
PrintService service = PrintServiceLookup
lookupDefaultPrintService();
DocFlavor flavor = DocFlavor
URL
GIF;
if (!service
isDocFlavorSupported(flavor))
{
System
err
println(
The printer does not support the appropriate DocFlavor
);
}
AttributeSet
正如你看到的
DocFlavor描述打印數據而且可以用來確定打印服務是否支持這種數據
然而
你的程序需要選擇一個基於那些支持的元素的打印機
例如
你要打印圖片用不同的顏色來描述不同的信息
你想知道提供的服務是否支持彩色打印
如果不
那麼要麼禁止它使用或者要求提供一個黑白圖片
類似彩色打印
兩邊打印或者使用不同的定位取決於打印機本身的屬性
而javax
print
attribute包包含了許多你可以用於描述這些屬性的包和接口
其中一個接口是前面提到的lookupPrintServices()中第二個參數AttributeSet
正如你願
它返回屬性的集合
在調用lookupPrintServices()指定一個不為空的值將返回支持這些屬性的打印服務
換句話說
如果DocFlavor和 AttributeSet都不為空
那麼方法將返回那些這兩種屬性都支持的打印機
Attribute
AttributeSet 是屬性的集合
一個顯而易見的問題是如何指定屬性的值呢? javax
print
attribute包裡同時含有一個叫Attribute的接口
你馬上可以看到通過調用add方法來給AttributeSet創建一個Attribute實例來獲得這個集合
在javax
print
attribute
standard包裡定義了大量你將要用到的接口
在之前
你可以查看javax
print
attribute這個包裡的其他接口
屬性模塊 目前為止
我們把屬性描述成打印服務的功能
而實際上在java支持的屬性中算很簡單的
對應每個屬性
java都有相應的模塊
只有遵循這些模塊屬性才有效
在不同的java打印服務位置使用不同的屬性
而不是所有的屬性在任何地方都適用
為了更好的理解這個
來看一下javax
print
attribute
standard 包裡定義的
OrientationRequested和 ColorSupported接口
創建一個新的打印文檔時可以指定OrientationRequested屬性和用於打印的定位
ColorSupported在你調用PrintService接口的getAttributes方法時返回
OrientationRequested是一個你用來傳給打印機的屬性
而ColorSupported是打印服務用來提供給你關於打印機能力信息的工具
你可以在創建打印文檔時把ColorSupported作為屬性指定
因為打印機是否支持彩色打印是你的程序不能控制的
接口和繼承 你第一次查看javax
print
attribute包裡的接口和類時你也許會感到選擇那些列表裡的接口和類很麻煩
除了Attribute 和AttributeSet和繼承AttributeSet的HashAttributeSet
javax
print
attribute包裡有
個子接口和類
列出在表
和圖
中
Table javaxprintattribute 裡定義的接口和類 Figure javaxprintattribute 包的一部分類的層次結構 那麼有了Attribute
AttributeSet
和 HashAttributeSet為什麼需要使用這些不同的接口和繼承類呢?是因為這些特殊的類是為那些特殊的屬性量身定做的
比方說
我提到過當你創建打印文檔的時候有個地方可以使用的屬性例如ColorSupported在那裡不能使用
當創建這樣的文檔
你可以使用DocAttributeSet接口(或者更專業一點
HashDocAttributeSet這個繼承的類)
這個繼承類只允許你添加繼承DocAttribute這個接口的屬性
這四種不同的模塊如下
·Doc: 在創建文檔時指定如何打印文檔
·PrintJob: 打印任務的屬性描述任務的狀態
·PrintRequest: 初始化打印時傳給任務的請求
·PrintService:由打印服務返回來描述打印機的功能
要知道如何工作
我們來創建一個DocAttributeSet的實例然後為AttributeSet設置DocAttributeSet和OrientationRequested屬性
HashDocAttributeSet定義了很好的結構
所有你可以很簡便的如下創建實例
DocAttributeSet 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);
attrs
add(ColorSupported
SUPPORTED);
早先提過
去指定是否支持彩色打印不恰當因為這不是程序所能控制的內容
換句話說
ColorSupported這個屬性放到一系列文檔屬性中並不合適
所以
運行先前的代碼當添加ColorSupported屬性時會拋出一個ClassCastException異常
要學習怎麼運行
記住每一個AttributeSet子接口都有一個相應Attribute子接口和繼承子類
當添加一個屬性時
繼承的子類試圖把Attribute作為參數給相應的子接口
這樣來確保只有當前適當的屬性會成功添加
這樣的話
HashDocAttributeSet 的add方法第一次和OrientationRequested的一個實例一起調用
並成功的把它作為一個object傳給DocAttribute
因為如圖
所示
OrientationRequested繼承了那個接口
與之相對應
傳ColorSupported實例的時候因為沒有繼承DocAttribute所以失敗了
Figure javaxprintattribute 包的一部分類的層次結構 這個例子舉例說明
表
裡的四個接口和類組來保證使用正確的屬性
注意模塊和不同的屬性之間有大量的交互
所以很多屬性與不止一個模塊關聯
例如
許多屬性繼承了PrintJobAttribute 和 PrintRequestAttribute因為大部分是通過一個相關的打印任務獲得提供給你的
你可以在初始化時指定它們
舉個例子
你可以把它加到PrintRequestAttributeSet中去來指定任務名
並且在打印的時候通過PrintJobAttributeSet來返回它
因此
JobName屬性類同時繼承PrintRequestAttribute 和 PrintJobAttribute
AttributeSet and HashAttributeSet 你已經知道了為什麼會有四個子類
但是AttributeSet接口和HashAttributeSet父類又是什麼呢?AttributeSet/HashAttributeSet在你不能確定要存儲在這個集合中的那些僅僅和一個模塊相關的屬性時使用
記得我以前提到的lookupPrintServices()方法允許你指定AttributeSet參數來限制返回的打印服務
表面上看來最好指定PrintServiceAttributeSet的實例
但是很多你可能用到的屬性並不繼承PrintServiceAttribute
我們假設你想要讓lookupPrintServices()方法返回支持彩色打印和風景畫打印的打印機
這些屬性與ColorSupported和OrientationRequested屬性關聯
但是請注意這些類並不共享模塊
前者是一個PrintServiceAttribute而OrientationRequested與另外三個模塊(Doc
PrintRequest
和 PrintJob)關聯
這意味著不存在單個的AttributeSet接口或類來同時包含ColorSupported和Sides屬性
創建AttributeSet的方法使用一個HashAttributeSet實例同時包含一個OrientationRequested 和 ColorSupported太簡單了
不像
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26216.html