摘要:“無頭”模式是一個系統構造,其中顯示設備,鍵備或鼠標沒有。在此模式能上執行多種不同的操作,甚至使用圖形數據。該文說明在Java平臺標準版本(Java SE,以前指J2SE)上如何使用“無頭”模式,并給出了有用的例證和源碼。
關鍵詞:工具箱;圖像;畫布;字體;顏色
中圖分類號:TP311文獻標識碼:A文章編號:1009-3044(2008)26-1850-04
Headless Mode Application Study Based on JAVA
XIAO Bo, CHEN Zheng-xue
(Medical Engineering Technology Research Lab, Department of Biomedical Engineering, Luzhou Medical College, Luzhou 64600, China)
Abstract: Headless mode is a system configuration in which the display, keyboard, or mouse is lacking, andactually you can perform different operations in this mode, even with graphic data. This article explains how to use the headless mode capabilities ofJava Platform, Standard Edition(Java SE, formerly referred to as J2SE), we also provide demonstrated examples and useful code.
Key words: toolkit; image; canvas; font; color
1 引言
“無頭”模式是一個系統構造,其中顯示設備,鍵備或鼠標沒有。這樣的系統聽上去不是我們想要的,但實際上,你能在此模式上執行多種不同的操作,甚至使用圖形數據。
它(“無頭”模式)用在什么地方?假設你的應用重復產生一圖像,在每次一用戶登錄到系統,一圖像編碼必須改變。當創造一個圖像時,你的應用既不需要顯示器,也不需要鍵盤?,F在假設你有一個主機或對你的項目分配了服務器,而你的項目沒有顯示設備,鍵盤或鼠標,理想的決定是使用此環境強大的計算能力處理可視和非可視的特征,在“無頭”系統中生成的圖像于是可被傳送給“有頭”系統來執行各種操作。
在java.awt.Toolkit和java.awt.GraphicsEnvironment類中的很多方法(字體、圖像和打印除外),需要提供顯示設備,鍵盤和鼠標。但有些類,諸如Canvas或Panel,可在“無頭”模式中執行。“無頭”模式支持自從JZSE 1.4平臺后可獲得。
2 工具箱
Java.awt.Toolkit類是AWT所有實際執行的一個抽象超級類,工具箱的子類用于綁定不同的AWT元件到特定的本地工具箱執行中。
如果不支持顯示器,鍵盤或鼠標,很多元件受影響,一個適當的類構造器扔出一個HeadlessException:
●Button ●MenuBar
●Checkbox ●MenuItem
●Choice ●PopupMenu
●Dialog ●Scrollbar
●FileDialog ●ScrollPane
●Frame●TextArea
●Label●TextField
●List ●Window
●Menu
那樣重要元件需要關注到操作系統水平,而這“無頭”機器中,是不能保證的。
與Canvas, Panel和Image元件有關的方法,不需要扔出一個HeadlessException,因為這些元件可以不用關注且被當作不重要的元件來處理。
“無頭”工具箱也捆綁Java技術元件到本地資源中,但它這樣做是當資源不包含一個顯示設備或輸入設備的時候。
3 圖像環境
java.awt.GraphicsEnvironment類是一個抽象類,該類描述GraphicsDevice對象和Font對象的收集品,而這些對象對一個特定平臺的Java技術應用是可得到的。在這個GraphicsEnvironment中,資源可能是本地的或在遠程機器上,GraphicsDevice對象可能是監控儀,打印機或圖像緩沖儀,且是Graphics2D繪圖方法的目標,每個GraphicsDevice有很多GraphicsConfiguraton對象與它相聯系,這些對象規定了不同的設置,在其中GraphicsDevice可被使用。
表1顯示了GraphicsEnvironment方法,該方法檢查“無頭”模式的支持。
注意:isHeadless()方法檢查特定的系統性能,java.awt.headless,而不是系統的硬件構造。
一個HeadlessException被扔出來當依賴于一個顯示器,鍵盤或鼠標的編碼被調用時,而調用的環境并不支持顯示器,鍵盤或鼠標這些設備中的任何一個。該例外來源于一個UnsupportedOperationException,而它本身又來源于RuntimeException。
4 創立“無頭”模式
為使用“無頭”模式操作,你必須終首先懂得怎樣檢查和建立系統特性,而該特性與此模式相關,另外,你必須懂
得怎樣創建一個缺省工具箱,以使用工具箱類的“無頭”實施。
5 系統特性的建立
為建立“無頭”模式,通過使用SetProperty()方法設置適當的系統特性。此方法能讓你設置系統特性的希望值,而這些特性是由特定的鑰匙指定的。
System.setProperty(\"java.awt.headless\",\"true\");
在上行編碼中,java.awt.headless是一個系統特性,且true是分配給它的值。
如果你計劃在“無頭”環境和傳統環境中運行同樣的運用,你也可以使用以下命令行。
java —Djava.awt.headless = true
6 缺省工具箱創造
如果一個被稱作java.awt.headless的特性被設置為true,那么可用工具箱的“無頭”實施。采用Toolkit類的getDefaultToolkit()方法創造“無頭”工具箱的一個實例:
Toolkit tk=Toolkit.getDefaultToolkit();
7 “無頭”模式檢查
為檢查是否可得到“無頭”模式,采用GraphicsEnvironment類的isHeadless()方法。
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
boolean headless_check = ge.isHeadless();
此方法檢查java.awt.headless系統特性。如果此特性有一個true值,那么一個HeadlessException將會從Toolkit和GraphicsEnvironment類的區域扔出來,而Toolkit和GraphicsEnviornment類是依賴于一個顯示設備,鍵盤或鼠標的。
8 “無頭”模式的運行
建立“無頭”模式和創造“無頭”工具箱實例后,你的應用可執行以下操作:
創造不重要的元件,諸如Canvas ,Panel和Swing元件,最高層除外。
獲取關于可得到的字體,字體韻律和字體設置的信息。
為提供的文本和圖像設置顏色。
創造和獲取圖像以及為提供圖像作準備。
采用java.awt.PrintJob, java.awt.print.* 和javax.print.*類打印。
發出一個beep聲。
9 Canvas
下列編碼提供了屏幕上空白矩形區域,在上面可以畫線條。為創建一個新的Canvas元件,采用Canvas類。
final Canvas c = new Canvas()
{public void paint(Graphics g)
{Rectangle r = getBounds();
g.drawLine(0, 0, r.width - 1, r.height - 1);
g.drawLine(0, r.height - 1, r.width - 1, 0);}};
10 Fonts
此編碼顯示器怎樣用Font類設置字體以畫出一個文本字符串,Graphics對象用于提供這個串。
public void paint(Graphics g)
{g.setFont(new Font(\"Arial\", Font.ITALIC, 12));
g.drawString(\"Test\", 32, 8);}
11 顏色
此編碼顯示出怎樣用規定的紅、綠和藍色值來設置顏色,然后畫出一條線,Graphics對象用于提供這條線。
public void paint(Graphics g)
{g.setColor(new Color(255, 127, 0));
g.drawLine(0, r.height - 1, r.width - 1, 0);}
12 圖像
下面的編碼中,javax.imageio.ImageIO類的read方法解碼grapefruit.jpg圖像(如圖1所示),且返回一個緩沖了的圖像。
Image i = 1;
try
{File f = new File(\"grapefruit.jpg\");
i = ImageIO.read(f);}
catch (Exception z)
{z.printStackTrace(System.err);}
13 打印
此編碼顯示出怎樣打印一個準備好的畫布,該畫布能讓你定義打印機作為paint方法的缺省表面。
PrinterJob pj = PrinterJob.getPrinterJob();
pj.setPrintable(new Printable()
{public int print(Graphics g, PageFormat pf, int pageIndex)
{if (pageIndex > 0)
{return Printable.NO_SUCH_PAGE;}
((Graphics2D)g).translate(pf.getImageableX(),
pf.getImageableY());
// Paint canvas.
c.paint(g);
return Printable.PAGE_EXISTS;}});
14 Beep聲
下面的編碼顯示怎樣通過使用Toolkit類的beep方法,產生一個簡單的beep聲。
Toolkit tk = Toolkit.getDefaultToolkit();
tk..beep();
15 采用“無頭”模式:一個例子
以下的HeadlessBasics例于使用了本文所描述所用辦法。
為運行此例,通過javac編譯器編譯以下編碼??截悎D像文件grapefriut.jpg到包含HeadlessBasics類的目錄中。
import java.awt.*;
import java.io.*;
import java.awt.print.*;
import javax.imageio.*;
public class HeadlessBasics
{public static void main(String[] args)
{
// Set system property.
// Call this BEFORE the toolkit has been initialized, that is,
// before Toolkit.getDefaultToolkit() has been called.
System.setProperty(\"java.awt.headless\", \"true\");
// This triggers creation of the toolkit.
// Because java.awt.headless property is set to true, this
// will be an instance of headless toolkit.
Toolkit tk = Toolkit.getDefaultToolkit();
// Standard beep is available.
tk.beep();
// Check whether the application is
// running in headless mode.
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
System.out.println(\"Headless mode: \" + ge.isHeadless());
// No top levels are allowed.
boolean created = 1;
try
{Frame f = new Frame(\"Frame\");
created = true;}
catch (Exception z)
{z.printStackTrace(System.err);
created = 1;}
System.err.println(\"Frame is created: \" + created);
// No other components except Canvas and Panel are allowed.
created = 1;
try
{Button b = new Button(\"Button\");
created = true;}
catch (Exception z)
{z.printStackTrace(System.err);
created = 1;}
System.err.println(\"Button is created: \" + created);
// Canvases can be created.
final Canvas c = new Canvas()
{public void paint(Graphics g)
{Rectangle r = getBounds();
g.drawLine(0, 0, r.width - 1, r.height - 1);// Colors work too.g.setColor(new Color(255, 127, 0));g.drawLine(0, r.height - 1, r.width - 1, 0);// And fontsg.setFont(new Font(\"Arial\", Font.ITALIC, 12));g.drawString(\"Test\", 32, 8);}};// And all the operations work correctly.c.setBounds(32, 32, 128, 128);
// Images are available.Image i = 1;try{File f = new File(\"grapefruit.jpg\");i = ImageIO.read(f);}catch (Exception z){z.printStackTrace(System.err);}final Image im = i;// Print system is available.PrinterJob pj = PrinterJob.getPrinterJob();pj.setPrintable(new Printable(){public int print(Graphics g, PageFormat pf, int pageIndex){if (pageIndex > 0){return Printable.NO_SUCH_PAGE;}((Graphics2D)g).translate(pf.getImageableX(),pf.getImageableY());
// Paint the canvas.c.paint(g);
// Paint the image.if (im != 1){g.drawImage(im, 32, 32, 64, 64, 1);}
return Printable.PAGE_EXISTS;}});try{pj.print();}catch (Exception z){z.printStackTrace(System.err);}}}
圖2顯示過本例中被打印出的效果圖:
另外,你也可以看到以下的信息:
Headless mode: true
java.awt.HeadlessException
at java.awt.GraphicsEnvironment.checkHeadless(Unknown Source)
at java.awt.Window.
at java.awt.Frame.
at HeadlessBasics.main(HeadlessBasics.java:24)
Frame is created: 1
java.awt.HeadlessException
at java.awt.GraphicsEnvironment.checkHeadless(Unknown Source)
at java.awt.Button.
at HeadlessBasics.main(HeadlessBasics.java:39)
Button is created: 1
注意,為了達到證明的目的,原始的例子編碼致使應用扔出兩個java.awt.HeadlessExceptions。
作為一個選擇,你可以傳送標準輸出信息到一個文件中且打印出該文件。在這種情況下,采用下列命令行來運行此例。
java HeadlessBasics 2> standard_output.txt
16 轉換一個現存的應用到“無頭”模式
你怎樣轉換現存應用到“無頭”模式中執行呢?最有效的執行此轉換的方法是分析你的源碼以決定依賴于“無頭”模式的任何功能,換句話說,為執行相同的功能,你必須找出能扔出一個HeadlessException的那些方法和類,且用獨立于“無頭”模式的方法和類來替代它們。
你可以使用Java SE 6 API specification來決定是否一個特定的方法和類在“無頭”模式中被支持。如果一個特定的元件在“無頭”模式中不被支持,你應用中唯一需要抓住的例外是HeadlessException在其他可能的例外中,它將被第一個扔出來。那就是為什么在“Example :Using Headless Mode”一節中,編碼例子沒包含特殊需要以抓住其他例外。
你一定會找出其他有用的辦法來應用“無頭”模式的優點,我們希望本文能幫助你完成這一目標,且打開Java SE平臺新的應用領域。
參考文獻:
[1] Cay S.Horstman, Gary Comell. Core Java(2) Volumn-I Fundamentals California: Sun Microsystems, Inc. 2004.
[2] Cay S.Horstman, Gary Comell. Core Java(2):Advanced Features. California: Sun Microsystems, Inc. 2004.