打造專業外觀-三
在《打造專業外觀-二》中,留下了3個未實現的功能:窗口標題和圖標,邊緣圓角,功能按鈕。在本篇中將實現這些功能來完結打造專業外觀-窗口部分的講解。
一、窗口標題。
SWT窗口Shell有public void setText(String string),public void setImage(Image image) 方法用來設置標題和圖標。但是現在窗口的樣式已經是SWT.NO_TRIM,不再有標題欄了,因此標題只能自己“畫”。在paintControl方法中添加如下代碼:
else if (e.getSource() == northPanel) {
String text = getText();
if (text != null) {
gc.setForeground(titleColor);
gc.drawText(text, e.width / 2 - gc.stringExtent(text).x / 2,
e.height / 2 - gc.stringExtent(text).y / 2, true);
}
Image image = getImage();
if (text == null) {
text = "";
}
if (image != null) {
gc.drawImage(image, e.width / 2 - gc.stringExtent(text).x / 2
- image.getBounds().width - 10, e.height / 2
- image.getBounds().height / 2);
}
}
標題文字居中顯示,圖標居標題文字10像素。代碼中“e.width”獲取繪圖環境上下文的長度,“gc.stringExtent(text).x”獲得標題文字的長度,“true”表示繪制的文字不需要背景,如果是false,會看到有明顯的灰色矩形作背景。繪制圖標不難理解。當然通常的標題欄是九宮格的“上部”面板,所以要為northPanel添加繪制監聽器。northPanel.addPaintListener(this);
二、邊緣圓角
如果你不熟悉SWT的Region使用,請先研讀http://www.eclipse.org/swt/snippets/中的“create a non-rectangular shell from a transparent image”程序。
該程序通過分析Image各個像素點的alpha值,來獲取Region的填充。你可以通過本地圖片實例化一個Image對象,支持透明的圖片格式有PNG和GIF兩種,美工都會知道這一點,本程序中用到的southwest.png、southeast.png、northeast.png、northwest.png均符合,以圖片透明度來實現不規則窗體是常用的方法,這樣做的好處是只要更換圖片就可達到改變窗體形狀。但是有些應用自身規定一種顏色為透明顏色,例如QQ,規定紫色為透明顏色,所以在它的實現中通過對圖片逐個像素點分析,發現RGB是紫色就認為是透明。好,原理大致如此。下面來定義一個函數來完成次功能:
private Region getImageTransparenceRegion(Image image, int offsetX,
int offsetY) {
Region region = new Region();
final ImageData imageData = image.getImageData();
if (imageData.alphaData != null) {
Rectangle pixel = new Rectangle(0, 0, 1, 1);
for (int y = 0; y < imageData.height; y++) {
for (int x = 0; x < imageData.width; x++) {
if (imageData.getAlpha(x, y) != 255) {
pixel.x = imageData.x + x + offsetX;
pixel.y = imageData.y + y + offsetY;
region.add(pixel);
}
}
}
}
return region;
}
該方法參考了Snippet21(http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet219.java?view=co),方法返回給定圖片透明部分構造的Region。然后在controlResized末尾添加如下代碼:
Region oldRegion = getRegion();
if (oldRegion != null && !oldRegion.isDisposed()) {
oldRegion.dispose();
}
Region newRegion = new Region();
newRegion.add(0, 0, getSize().x, getSize().y);
newRegion.subtract(getImageTransparenceRegion(northwestImage, 0, 0));
newRegion.subtract(getImageTransparenceRegion(northeastImage,
getSize().x - northeastImage.getBounds().width, 0));
newRegion.subtract(getImageTransparenceRegion(southwestImage, 0,
getSize().y - southwestImage.getBounds().y));
newRegion.subtract(getImageTransparenceRegion(southeastImage,
getSize().x - southeastImage.getBounds().width, getSize().y
- southeastImage.getBounds().height));
setRegion(newRegion);
Shell實例通過setRegion(Region region)設置區域來實現不規則巨型窗體,但是前提是把樣式設置成SWT.NO_TRIM。
由于窗體尺寸的變更相應的區域也要跟著調整,所以要把邏輯寫在controlResized方法中,而且每次改變過后要釋放Region資源并重新設置新的區域。上述在初始化Region對象后,“newRegion.add(0, 0, getSize().x, getSize().y);”方法將覆蓋窗口整個區域,隨后的subtract挖掉四個角落的透明部分。
三、功能按鈕
出于時間比較緊,只添加關閉按鈕,其他按鈕如最小化、最大化原理相同。
通常按鈕有四種狀態,分別是:正常態、鼠標在上方、鼠標按下、被禁用。這4態對應4個圖標。由于時間關系,只對需要注意的地方簡單介紹。具體見完整代碼。
無疑,4種狀態切換要添加鼠標事件監聽器。關閉按鈕通過聲明private Composite closeButton;來實現。具體位置本程序實現是右端與northeastPanel相鄰,左邊與northPanel相鄰。在鼠標抬起時,要檢查抬起點是否在該按鈕上,如果是才執行關閉操作。見如下代碼
if (e.x > 0 && e.x < closeButton.getSize().x && e.y > 0
&& e.y < closeButton.getSize().y){
// 執行關閉操作,否則鼠標在關閉按鈕上方按下,但是不在其上松開,表明用戶放棄關閉行為。
}
重寫dispose方法如下:
@Override
public void dispose() {
try {
northwestImage.dispose();
northeastImage.dispose();
northImage.dispose();
southwestImage.dispose();
southeastImage.dispose();
southImage.dispose();
westImage.dispose();
eastImage.dispose();
closeImage.dispose();
closeOverImage.dispose();
color1.dispose();
color2.dispose();
titleColor.dispose();
} finally {
super.dispose();
}
}
首先是釋放所有SWT本地資源,然后是super.dispose();釋放窗口資源。
運行程序,界面效果如下
至此,打造專業外觀-窗口部分的講述就結束了,在這3篇幅中,主要講述了九宮格的概念,九宮格法俗話說就是“貼圖”,這個手法最常用也是最基礎的,你會發現界面美觀與否與圖片有很大關系,同時桌面編程人員需要頻繁與美工交互才能達到理想效果,如果沒有合格的美工,但憑技術很難實現漂亮的外觀,不過確實也存在只用多邊形與曲線繪制組件的高手,swing的L&F就是這么實現的,但是貼圖的好處是只要圖片替換,外觀也跟著替換,不用更改代碼。
本程序只作為您設計的參考,欠缺還很多,并且沒有對代碼的健壯性、異常情況過多考慮,由于swt資源必須手工釋放,如dispose方法中那樣,其實那是最基本的,在實際環境下這么做還很有限,而且nullPoint異常也沒有過多考慮。這都需要你自己去實現。
最終的完整程序這里下載
posted on 2007-11-07 00:49 sun_java_studio@yahoo.com.cn(電玩) 閱讀(6459) 評論(6) 編輯 收藏 所屬分類: NetBeans 、GUI Design