亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術文章
文章詳情頁

Java高級編程:打印--學習如何使用打印服務API

瀏覽:69日期:2024-06-12 14:52:52
內容: Java高級編程:打印--學習如何使用打印服務API作者:Brett Spell翻譯:ice_x版權聲明:可以任意轉載,轉載時請務必以超鏈接形式標明文章原始出處和作者信息及本聲明英文原文地址:http://www.javaworld.com/javaworld/jw-07-2005/jw-0725-print.html中文地址:http://www.matrix.org.cn/resource/article/43/43658_java_print.html關鍵詞: Java Programming print PrintJob摘要在這篇文章里,來自Pro Java Programming (Apress, June 2005)專家Brett Spell解釋了如何一步一步的定位打印設備,創建打印工程,創建一個Doc文檔接口的實例來描述你想要打印的數據并且初始化打印。(4500字,2005年7月25日)Java自從問世以來在各方面發展迅速,但是一直以來,打印輸出是java最弱的方面。事實上,java1.0不支持任何打印功能。Java1.1在java.awt包里包含了一個叫做PrintJob的類,但是這個類提供的打印功能十分粗糙和不可靠。當java1.2問世,它圍繞PrinterJob設計了一個完整獨立的打印機制(叫做java2D printing API),并且在java.awt.print包里定義了一些新的類和接口。這些使得基于PrintJob打印機制(就是AWT printing)基本荒廢,雖然PrintJob從未被抨擊而且至少在這篇文章里仍然是一個提供技術的類。在J2SE1.3里當PrintJob的功能擴展到可以通過在java.awt包里的JobAttributes 和PageAttributes兩個類設定工程和頁面的屬性時發生了一些額外的改變。隨著J2SE1.3的發布,打印功能相應的得到了完善;但是在混合使用這兩種完全不同的打印機制的時候仍然存在一些問題。比如,這兩種機制使用java.awt.Graphics這個類的一個接口來展現打印內容,意味著所有要打印的東西都必須用一張圖片表示。另外,完善的PrintJob提供了很有限的工程相關屬性的設置;這兩種機制都沒有辦法通過程序來選擇目標打印機。Java打印最大的改變來自于J2SE的發布帶來的Java打印服務API。這個第三代Java打印支持接口突破了先前提到的使用javax.print包的PrintService和DocPrintJob接口的局限性。因為新的API就是以前兩種舊的打印機制定義的功能函數的一個父集,它是目前我們常用的方法并且是這篇文章的焦點。更深入來說,以下的步驟包含了怎么使用這個新的Java打印服務API:1.定義打印機,限制那些返回到提供你要實現功能的函數的列表。打印服務實現了PrintService接口.2.通過調用接口中定義的createPrintJob()方法創建一個打印事件,作為DocPrintJob的一個實例。3.創建一個實現Doc接口的類來描述你想要打印的數據 , 你也可以創建一個PrintRequestAttributeSet的實例來定義你想要的打印選項。4.通過DocPrintJob接口定義的printv()方法來初始化打印,指定你先前創建的Doc,指定PrintRequestAttributeSet或者設為空值?,F在你可以檢查每一步并且試著完成它們。注意 在這篇文章里,我將交替使用打印機和打印服務,因為在大部分情況下,打印服務不亞于一臺真實的打印機。 一般的打印服務反映了理論上可以發送到不僅僅是打印機的的輸出。舉例來說,打印服務也許根本不能打印東西但是可以往磁盤上的文件寫數據。換句話說,所有的打印機可以看成是特殊的打印服務,但是并不是所有打印服務和打印機有聯系。就像你一般把你的文本送到打印機那里一樣,我有時候使用更為簡便的打印機這個名詞來代替技術上更精確的打印服務。 定義打印服務你可以使用在PrintServiceLookup類中定義的三種靜態方法中的一種來定義。最簡單的一種就是lookupDefaultPrintService(),正如它的名字一樣,它返回一個你默認的打印機:PrintService service = PrintServiceLookup.lookupDefaultPrintService(); 雖然用這個辦法很簡單也很方便,用它來選擇你的打印機意味著用戶的打印機一直都支持你的程序所要精確傳輸的數據輸出。實際上,你真正想要的是那種可以處理你想要的數據的類型并且可以支持你要的特征例如顏色或者兩邊打印。為了從列表中中返回你所要求的特殊功能支持的打印機,你可以使用剩下兩個方法中的lookupPrintServices() 或者lookupMultiDocPrintServices()。lookupPrintServices()方法有兩個參數:一個DocFlavor的實例和實現AttributeSet接口的實例。你馬上將看到,你可以使用兩者中任意一個來限制返回的打印機,但是lookupPrintServices()允許你指定這兩個參數為空值。如果把兩者都設為空,那么你得到的返回值將是任意一個可用的打印機。在這種情況下,你并不需要查看PrintService中定義的方法,其中一個getName()方法返回了一個字符串,代表打印機的名字。你可以編譯下面的代碼來列出你的系統現有的打印機:PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);for (int i = 0; i < services.length; i++) { System.out.println(services[i].getName());} 例如你的系統名為PrintServer,下面有Alpha, Beta, 和Gamma 打印機,用以上代碼可以得到以下輸出: PrintServerAlphaPrintServerBetaPrintServerGamma 現在查看那些你可以傳給lookupPrintServices()方法的參數來看看如何返回擁有特殊功能的打印機。DocFlavor第一個你可以指定的參數是一個DocFlavor類的實例,它描述了將要打印的數據的類型和數據如何存儲。在大部分情況下,并不需要去創建一個新的實例因為Java包含了很多預先定義的實例,使得你可以用它們來傳給lookupPrintServices()。然而,我們還是來看一下DocFlavor的結構和方法來探討打印服務如何使用這個實例。創建DocFlavor實例需要的兩個參數都是字符串,一個是MIME (Multipurpose Internet Mail Extensions)類型另一個是類的名字。MIME類型被用于描述數據類型。例如,你要打印一個gif文件,你需要使用MIME類型是image/gif的DocFlavor。相類似,如果你要打印HTML文件里的文本信息要使用MIME類型似text/plain或者text/html。表現類MIME類型描述將要打印的數據的類型,表現的類則表示如何讓打印服務得到這些數據。DocFlavor包含了幾個靜態的內部類,每一個相對應一個表現類和如何裝載要打印得數據。表1中列出了上面提到的內部類和表現類。注意在SERVICE_FORMATTED(一會我會更詳細地解釋)旁邊,每一個和'binary'或者 'character'相對應。事實上,這些差別是人為的,因為'character'數據類型本身就是一種特殊的binary類型。這種情況下,我們說的二進制(binary)數據包括人們可以看懂的字符和一些格式化的字符比如tabs,換行回車等。當然,這些差別很重要,反映出面向字符的表現類并不適合存儲二進制數據。例如,你不會用字符隊列或者字符串來保存一個gif文件,你也不能通過Reader接口來訪問它。另一方面,因為字符也是一種特殊的二進制數據,它完全適合儲存文本信息到字節數組里或者通過InputStream或者一個URL來訪問它。Table 1. DocFlavor的表現類上面定義的任何一個靜態內部類相對應一個表現類,但是請記住我說過每一個DocFlavor的實例通過一個表現類和一個MIME來確認要打印的數據的類型。要訪問這樣一個實例,你要通過表1總列出的內部類。例如,我們假設你要打印一個在網上通過URL訪問的gif文件,這樣的話,就選擇表現類是javav.net.url,對應的在DocFlavor中的靜態類就是URL類。如果你打開那個內部類的文檔,你會發現其實它定義了一系列靜態的內部類,每一個對應一種打印機支持的MIME類型。表2描述了在DocFlavor.URL里的內部類和MIMETable 2. The DocFlavor.URL inner classes 因為要通過URL打印gif圖片,你可以用一下代碼來獲得實例DocFlavor flavor = DocFlavor.URL.GIF; 這個代碼創建了一個DocFlavor實例,代表類是java.net.URL,MIME是image/gif。表2列出的了DocFlavor.URL的類,那么其他六個內部類呢?我們等下來討論一下SERVICE_FORMATTED,這之前,看看與二進制數據聯系的所有三種類型(BYTE_ARRAY, INPUT_STREAM, and URL)相關的內部類。例如,如果你把gif儲存到了一個字節數組里,那么你可以用以下代碼:DocFlavor flavor = DocFlavor.BYTE_ARRAY.GIF; 正如有三個與二進制類型關聯的內部類一樣,與字符類型相關的另外三個類列在表3里 Table 3. CHAR_ARRAY, READER, and STRING 所以,如果你想打印儲存在字符串中的文本數據,用以下代碼:DocFlavor flavor = DocFlavor.STRING.TEXT_PLAIN; 類似,如果文本來自于網頁上的HTML文檔,用以下代碼:DocFlavor flavor = DocFlavor.STRING.TEXT_HTML; 選擇正確的打印機還記得我們在開始關于討論DocFlavor之前關于打印機的那個精確支持你想要打印的數據類型的假設嗎?這似乎看起來沒有必要。實際上,你會對給你的打印機所支持的文檔類型感到吃驚。例如,剛提到文本類型看起來似乎是最容易支持的,所以,如果你的程序要打印一個普通文本或者HTML文本,你可以隨便選擇一個打印服務并把它送到打印機那去。然而大部分打印機不支持基于文本的表現類,如果你試圖向打印機發送它不支持的DocFlavor,會產生下面的異常:Exception in thread 'main' sun.print.PrintJobFlavorException: invalid flavor at sun.print.Win32PrintJob.print(Win32PrintJob.java:290) at PrintTest.main(PrintTest.java:11) 現在你已經知道了如何得到一個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包里有4個子接口和類,列出在表4和圖1中。Table 4. javax.print.attribute 里定義的接口和類 Figure 1. javax.print.attribute 包的一部分類的層次結構. 那么有了Attribute, AttributeSet, 和 HashAttributeSet為什么需要使用這些不同的接口和繼承類呢?是因為這些特殊的類是為那些特殊的屬性量身定做的。比方說,我提到過當你創建打印文檔的時候有個地方可以使用的屬性例如ColorSupported在那里不能使用。當創建這樣的文檔,你可以使用DocAttributeSet接口(或者更專業一點,HashDocAttributeSet這個繼承的類),這個繼承類只允許你添加繼承DocAttribute這個接口的屬性。這四種不同的模塊如下:&#61623; Doc: 在創建文檔時指&#61623; 定如何打印文檔&#61623; PrintJob: 打印任務的屬性描述任務的狀態 &#61623; PrintRequest: 初始化打印時傳給任務的請求 &#61623; PrintService:由打印服&#61623; 務返回來描述打印機的功能要知道如何工作,我們來創建一個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。因為如圖2所示,OrientationRequested繼承了那個接口。與之相對應,傳ColorSupported實例的時候因為沒有繼承DocAttribute所以失敗了。Figure 2. javax.print.attribute 包的一部分類的層次結構 這個例子舉例說明,表4里的四個接口和類組來保證使用正確的屬性。注意模塊和不同的屬性之間有大量的交互,所以很多屬性與不止一個模塊關聯。例如,許多屬性繼承了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太簡單了。不像它的子類,它并不限制你往上加特殊的屬性,所以可以用以下代碼成功執行:AttributeSet attrs = new HashAttributeSet();attrs.add(ColorSupported.SUPPORTED);attrs.add(OrientationRequested.LANDSCAPE);PrintService[] services = PrintServiceLookup.lookupPrintServices(null, attrs); 通過用戶界面的打印機選擇就此觀點而言,我認為使用的打印機應該由應用程序計劃選擇。但操作過程中,打印輸出內容時往往會顯示一個對話框讓用戶選擇。幸運的是,Java通過使用ServiceUI類(在javax.print包中定義)中的靜態printDialog()方法使得這些操作簡單化。在顯示的對話框旁邊,僅在調用printDialog()時必須指定的參數值如下:用戶可選用的PrintService實例數組。默認的PrintService。PrintRequestAttributeSet實例。這用來彈出顯示的對話框,并在對話框消失之前返回用戶所作的任何更改。要解釋這些如何運作,可使用下列簡單的代碼段來顯示打印對話:PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);PrintService svc = PrintServiceLookup.lookupDefaultPrintService();PrintRequestAttributeSet attrs = new HashPrintRequestAttributeSet();PrintService selection = ServiceUI.printDialog( null, 100, 100, services, svc, null, attrs); 運行時,代碼產生如圖例3中所示的對話框Figure 3. The printer dialog 隨著代碼的說明,從printDialog()方法返回的值是一個PrintService實例,識別用戶所選的打印機,或在用戶取消打印機對話時識別為空。此外,PrintRequestAttributeSet已更新到可通過對話框來反映用戶作出的更改,比如要打印的份數。通過使用printDialog()方法,可讓用戶選擇其輸出要發往的打印機,提供用戶對于專業應用程序的期望功能。創建打印任務這是打印中的一個簡單步驟;因為一旦獲得PrintService的一個參考,你需要做的就是調用createPrintJob()方法,如:PrintService service;...DocPrintJob job = service.createPrintJob(); 代碼中顯示,從createPrintJob()返回的值是一個DocPrintJob實例,可讓您控制并監控打印操作的狀態。要啟動打印,您會調用DocPrintJob對象的print()方法,但是,這之前,您需要定義待打印的文檔或選用PrintRequestAttributeSe。您已經知道如何構造并彈出AttributeSet,這個步驟不再重復,接下來,您將了解定義待打印的文檔。定義要打印的文檔接下來這一步是定義要打印的文檔,用一個在javax.print包里的Doc的接口實例來創建。每一個Doc的實例有兩個必須定義的屬性和一個可選擇的屬性:&#61623; Object 代表要打印的內容&#61623; DocFlavor的一個實例描述數據類型&#61623; 可選的DocAttributeSet 包含打印時的屬性復習Doc接口的文檔可以看出javax.print包里包含了一個叫SimpleDoc 的接口的繼承,它的構造函數包含了上面三個參數。要知道如何構建SimpleDoc 的實例,我們假設你要打印兩份存在http://www.apress.com/ApressCorporate/supplement/1/421/bcm.gif的gif文件拷貝。我們要做的就是構建一個SimpleDoc實例來描述這個文檔創建了一個URL來指向圖片,并且引用了DocFlavor,并把這兩個傳給SimpleDoc構造函數:URL url = new URL( 'http://www.apress.com/ApressCorporate/supplement/1/421/bcm.gif');DocFlavor flavor = DocFlavor.URL.GIF;SimpleDoc doc = new SimpleDoc(url, flavor, null); 啟動打印打印的最后一個步驟就是調用DocPrintJob的 print()方法,傳遞待打印數據的Doc對象,或選用PrintRequestAttributeSet實例。為簡單起見,假設默認打印機支持你所需要的flavor和屬性,在此情況下要使用下列代碼將上一個例子提及的gif文件打印兩份:PrintService service = PrintServiceLookup.lookupDefaultPrintService();DocPrintJob job = service.createPrintJob();URL url = new URL( 'http://www.apress.com/ApressCorporate/supplement/1/421/bcm.gif ');DocFlavor flavor = DocFlavor.URL.GIF;Doc doc = new SimpleDoc(url, flavor, null);PrintRequestAttributeSet attrs = new HashPrintRequestAttributeSet();attrs.add(new Copies(2));job.print(doc, attrs) 注意,一些情況下,打印不同步執行,這可能會在實際打印完成之前返回對print()的調用。關于作者Brett Spell是一個Frito-Lay的高級程序開發者并寫了Pro Java Programming 的初始版本。 資源這是Pro Java Programming, Second Edition, Brett Spell (Apress, June 2005; ISBN: 1590594746):第十章“打印的一部分 http://www.apress.com/book/bookDisplay.html?bID=421 要得到更多關于java API的文章,點擊以下鏈接http://www.javaworld.com/channel_content/jw-apis-index.shtml Java, java, J2SE, j2se, J2EE, j2ee, J2ME, j2me, ejb, ejb3, JBOSS, jboss, spring, hibernate, jdo, struts, webwork, ajax, AJAX, mysql, MySQL, Oracle, Weblogic, Websphere, scjp, scjd Java高級編程:打印--學習如何使用打印服務API作者:Brett Spell翻譯:ice_x版權聲明:可以任意轉載,轉載時請務必以超鏈接形式標明文章原始出處和作者信息及本聲明英文原文地址:http://www.javaworld.com/javaworld/jw-07-2005/jw-0725-print.html中文地址:http://www.matrix.org.cn/resource/article/43/43658_java_print.html關鍵詞: Java Programming print PrintJob
標簽: Java
相關文章:
主站蜘蛛池模板: 欧美日韩亚洲国产精品 | xvideos国产在线视频 | 黄色网址播放 | 国产视频xxxx | 国产精品视频网站你懂得 | 久久综合一本 | 国产农村妇女一级毛片视频片 | 成年女人毛片免费观看不卡 | 国产剧情精品在线 | 久草在线资源福利站 | 成人免费的性色视频 | 久久精品a亚洲国产v高清不卡 | 国产亚洲精品一区二区 | 一本一本大道香蕉久在线精品 | 国产一级aaa全黄毛片 | 一级毛片成人免费看免费不卡 | 131美女爱做免费高清视频 | 丰满老妇猛交视频 | 亚洲综合男人的天堂色婷婷 | 精品全国在线一区二区 | 妞干网这里只有精品 | 成人啪啪www | 国产大片视频免费观看 | 精品自拍视频在线观看 | 亚洲黄色一级毛片 | 国产亚洲精品一区在线播 | 黄色免费观看视频 | 99青草青草久热精品视频 | 91久久老司机福利精品网 | 国产伦精品一区二区三区免费观看 | a男人的天堂久久a毛片 | 一级毛片免费观看久 | 丁香五月好婷婷深深爱 | 久久精品国产99国产精偷 | 窝窝午夜精品一区二区 | 亚洲精品国产第一区第二区国 | 日韩精品视频免费观看 | 国产区视频 | 青青青操| 青青青青手机在线视频观看国产 | 视频在线一区二区三区 |