Java桌面技術

          Java Desktop Technology

          常用鏈接

          統計

          友情連接

          最新評論

          打造專業外觀-三

          在《打造專業外觀-二》中,留下了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

          評論

          # re: 打造專業外觀-三[未登錄] 2007-11-07 13:14 Thinker

          受用  回復  更多評論   

          # re: 打造專業外觀-三 2007-11-07 19:06 William Chen

          Hi 電玩,
          文章寫的不錯,項目也做的非常漂亮。SWT都被你做成這個樣子,佩服。
          我對SWT并不太熟,稍有了解。其實對于swing,我也只是個人偏愛,至于SWT總有它適合的地方。我的文章的目的主要是糾正人們對于Swing的誤解,希望人們不要對SWT過于迷信。所謂糾往必須過正嘛。
          實際上沒有正確與錯誤的技術,只有合適不合適的技術。
          以前覺得國內都在搞Server Side Java,難得在這兒看到有這么多人對Java GUI感興趣,而且技術都相當不錯啊。
          最近Java應用桌面開發逐漸升溫,加上Sun對于桌面Java態度的改變,Java的開源,這些都必將促進Java桌面技術的復興。
          Java桌面技術前途還是比較光明的。  回復  更多評論   

          # re: 打造專業外觀-三[未登錄] 2007-12-12 16:16 xiaoxiao

          高手們,能不能加上最小化和最大化按鈕。初學者  回復  更多評論   

          # 打造專業外觀-三 2008-05-22 15:51 swt

          謝謝啊,收下了!!  回復  更多評論   

          # re: 打造專業外觀-三 2008-05-24 14:12 一嘯長天

          是啊....轉做WEB也是一種無柰之舉啊!  回復  更多評論   

          # re: 打造專業外觀-三 2008-05-24 15:19 sun_java_studio@yahoo.com.cn(電玩)

          @一嘯長天
          Web是大趨勢,但是不一定就是HTML,RIA的興起將會帶來一場革命,Flex、JavaFX和桌面程序開發很像。  回復  更多評論   

          TWaver中文社區
          主站蜘蛛池模板: 两当县| 乳源| 龙州县| 正安县| 墨江| 新闻| 沂水县| 鄂托克旗| 建始县| 遂平县| 沧州市| 金乡县| 宣恩县| 峨眉山市| 手游| 剑河县| 金川县| 南澳县| 萝北县| 陈巴尔虎旗| 永昌县| 巫溪县| 广汉市| 洛阳市| 阿勒泰市| 德令哈市| 龙州县| 睢宁县| 凤冈县| 额济纳旗| 绍兴市| 平山县| 青田县| 邵阳市| 安国市| 图们市| 郑州市| 兴山县| 霞浦县| 中牟县| 常山县|