Java桌面技術

          Java Desktop Technology

          常用鏈接

          統計

          友情連接

          最新評論

          打造專業外觀-二

          在上一篇《打造專業外觀-九宮圖》,介紹了九宮格的概念并留下了一個演示程序。那個程序只是一個渲染過的窗口,許多必要的功能尚未實現,比如拖拽移動、改變大小、標題欄雙擊等。好現在就來一一實現。
          你首先從這里下載上一篇程序的代碼,然后在eclipse中打開。
          一、拖拽移動與雙擊標題欄。
          為DemoShell類添加下列成員
          private Point location;
          注意:導入的時候仔細看import語句。import org.eclipse.swt.graphics.Point;而不是import java.awt.Point;
          窗體的拖拽操作一般是拖拽窗體的標題欄,所以實現的思路就確定在northPanel了。方法就是為northPanel(充當標題欄)添加鼠標事件監聽器。
          northPanel.addMouseListener(this);
          northPanel.addMouseMoveListener(this);
          然后使DemoShell實現ControlListener、MouseListener、MouseMoveListener接口,并生成接口方法。
          在mouseDoubleClick方法中添加如下代碼:
          if (e.getSource() == northPanel) {
             setMaximized(!getMaximized());
            }
          首先判斷如果雙擊是northPanel發起的,那么立即改變狀態,只需一句話即可。
          在mouseDown添加如下代碼:
          if (e.getSource() == northPanel) {
             if (!getMaximized()) {
              location = new Point(e.x, e.y);
             }
            }
          同理,要判斷是否是northPanel發出的雙擊事件。然后在窗口不是最大化時再為location賦值,注意,是在窗口不是最大化時,否則location就應該為null。之所以這么做是當窗體呈最大化狀態時不應該移動,道理不難理解。
          然后在mouseUp方法中添加如下代碼:
          if (e.getSource() == northPanel) {
             location = null;
            }
          當鼠標抬起時,釋放location。
          接下來是最重要的mouseMove方法。該方法如下:
          public void mouseMove(MouseEvent e) {
            if (e.getSource() == northPanel) {
             if (location != null) {
              Point p = getDisplay().map(this, null, e.x, e.y);
              setLocation(p.x - location.x, p.y - location.y);
             }
            }
           }
          注意:有對location不空的判斷。map(Control from, Control to, int x, int y)函數是坐標轉換,把from組件上的(x,y)坐標轉換成to組件的坐標。null表示to組件就是桌面。如果你仔細研讀《SWT自定義組件之Slider》就會比較容易理解。
          現在你可以運行程序,發現窗口可以拖拽了。

          二、改變大小
          添加如下變量聲名
          private Point size;
          然后在mouseDown方法中追加如下語句
           else if (e.getSource() == southeastPanel) {
             size = new Point(e.x, e.y);
            }
          在mouseUp中追加如下語句
          else if (e.getSource() == southeastPanel) {
             if (size == null) {
              return;
             }
             setSize(new Point(getBounds().width + e.x - size.x,
               getBounds().height + e.y - size.y));
             size = null;
            }
          其原理同上。
          這個時候可以改變尺寸了,再添加如下功能畫龍點睛。
          private Cursor seCursor = new Cursor(getDisplay(), SWT.CURSOR_SIZESE);

           private Cursor titleCursor = new Cursor(getDisplay(), SWT.CURSOR_SIZEALL);
          southeastPanel.setCursor(seCursor);
          northPanel.setCursor(titleCursor);
          好。現在運行程序觀察下結果,但是美中不足的是,當拖拽右下角改變尺寸時,沒有一個虛線來指示,能不能像前面《SWT自定義組件之Slider》虛擬劃塊那樣實現呢,答案是不能,究其原因是Java支持的繪圖操作還只能以組件為畫布,不能實現在桌面上繪圖,有待SWT、AWT(swing不行)在底層提供了這一功能。由于時間關系,只能先介紹移動、改變大小的實現。最小化、最大化、關閉等功能按鈕,圓角,標題欄文字等的實現,以后再做介紹。不過您可以嘗試標題欄文字著一功能,很簡單,為northPanel添加addPaintListener即可。
          改進后的代碼這里下載

          posted on 2007-11-04 20:12 sun_java_studio@yahoo.com.cn(電玩) 閱讀(6874) 評論(9)  編輯  收藏 所屬分類: NetBeansGUI Design

          評論

          # re: 打造專業外觀-二 2007-11-05 03:06 歡樂豬

          >>>究其原因是Java支持的繪圖操作還只能以組件為畫布,不能實現在桌面
          >>>上繪圖,有待SWT、AWT(swing不行)在底層提供了這一功能。

          在Display上畫圖就相當于在桌面上畫。
          GC gc = new GC(display);
          .....

          另外GC.setAlpha(int alpha)可以控制透明度。

          ===================================================

          >>>但是美中不足的是,當拖拽右下角改變尺寸時,沒有一個虛線來指示,
          >>>能不能像前面《SWT自定義組件之Slider》虛擬劃塊那樣實現呢

          這個功能要自己在桌面上畫的話挺費勁的,
          可以考慮用一個Tracker(SWT.RESIZE)。  回復  更多評論   

          # re: 打造專業外觀-二 2007-11-05 08:31 Matthew Chen

          老是想到有個什么東西可以,原來是Tracker,swt sample里有。還有就是swing實現透明窗格,最近才知道還有個jna,看這里:http://www.aygfsteel.com/ruislan/archive/2007/10/24/154689.html
          只是不知是否可以跨平臺了,我以前一直覺得只要能有透明窗格,swing也能有Tracker這樣的東西了,現在又不確定了,因為透明ms上面的一切都變透明了,不知畫出來的線還看不看得到,不然就只有用toolkit里的取capture的方法模擬桌面來實現。
          還有個問題,為什么我以前裝ubuntu的時候java不提供win L&F,在win下也不提供GTK L&F,如果是許可證的問題那我們以后要怎么用它的皮膚啊。  回復  更多評論   

          # re: 打造專業外觀-二 2007-11-05 09:59 sun_java_studio@yahoo.com.cn(電玩)

          @Matthew Chen
          如果C水平足夠強的話,完全可以彌補AWT SWT處理半透明等能力的不足,jna就是C。但是Java開發員當然期望這一切集成在Java中,Sun之所以計劃在JDK1.7中實現這一功能,Vista的刺激是很重要的原因,AWT要實現不規則窗體、半透明窗體不是那么容易,原因不在AWT與技術難度,是因為接口得重新寫,還要考慮跨平臺和向前兼容,即使在JDK中有對應的功能,對于某些不支持透明的OS也無能為力。Sun公司AWT研發在俄羅斯,Swing研發在美國,彼此的協商也是一定問題,為蘇聯老大哥祈禱吧。  回復  更多評論   

          # re: 打造專業外觀-二 2007-11-05 10:02 sun_java_studio@yahoo.com.cn(電玩)

          @歡樂豬
          關于SWT的技術我主要來自http://www.eclipse.org/swt/snippets/和www.java2s.com。后來青睞swing后一直沒怎么關注  回復  更多評論   

          # re: 打造專業外觀-二 2007-11-05 16:57 原來只潛水的人

          精彩  回復  更多評論   

          # re: 打造專業外觀-二 2007-11-05 19:33 歡樂豬

          >>> 透明窗格
          ----------------------------------------------------------------
          不通過JNI,透明窗格根本沒法實現,因為那是窗口子系統的一個特性。
          窗口子系統不支持的話,誰也沒則。 Windows 2000就不支持, 據說
          Linux采用的X Window也不支持。 最早是macosx實現的,Microsoft直到
          XP才有。SWT沒有加入這個功能,可能是因為受到太多有關平臺之間差異性
          的批評,和不支持的平臺太多也有關。其實完全可以提供,如果平臺不支持就忽略。像SWT一貫的做法,我覺得挺好。

          可以模擬,像Matthew Chen說的是一種方法,缺點是得啟動一個Timer。

          還有一個模擬的法子,
          SWT的Snippets中有, 叫emulate transparent shell。就是用Non-Rectangle的Shell, 把Shell鏤空,像一張網一樣,只要網格夠小,
          看起來就是透明的。不用Timer,跨平臺,只不過不好控制透明度。


          不然就得JNI了, MS Windows下
          void setWindowTransparency(int hwnd, int alpha) {
          byte byteAlpha = (byte) alpha;
          int style = OS.GetWindowLong(hwnd, OS.GWL_EXSTYLE);
          OS.SetWindowLong(hwnd, OS.GWL_EXSTYLE, style |
          OS.WS_EX_LAYERED);
          OS.SetLayeredWindowAttributes(hwnd, 0, byteAlpha,
          OS.LWA_ALPHA);
          }

          hwnd用Shell.handle。 就把一個不透明的Shell,改成透明度為alpha
          的Shell了, alpha在0到256之間, 0是全透明。3個C函數SWT的
          OS都已經做好對應,省了很多麻煩。

          懶得寫文章,就接LZ的帖子和大家分享些經驗了。
            回復  更多評論   

          # re: 打造專業外觀-二 2007-11-06 00:57 sun_java_studio@yahoo.com.cn(電玩)

          @歡樂豬
          我不明白OS.SetLayeredWindowAttributes函數和OS.LWA_ALPHA還有OS.WS_EX_LAYERED是怎么出來的。是在3.3版運行的么。
          JNI,Swing的Java2D也用JNI實現的,我說過如果C足夠強的話,不在乎你用什么WT,Sun的同事就做過這些。  回復  更多評論   

          # re: 打造專業外觀-二 2007-11-06 03:29 歡樂豬

          是啊, org.eclipse.swt.internal.win32.OS是SWT的一個非API類。當然你得用windows的SWT版本。我是在3.4M2下試的,好像不是新加上的,3.3應該早就有了  回復  更多評論   

          # re: 打造專業外觀-二 2008-06-25 11:22 yunjitang

          太棒了。正是我所想要的。學習研究中  回復  更多評論   

          TWaver中文社區
          主站蜘蛛池模板: 京山县| 勃利县| 宁海县| 定日县| 通河县| 永嘉县| 甘泉县| 儋州市| 额济纳旗| 苍山县| 平山县| 海门市| 筠连县| 东安县| 海口市| 利津县| 东兰县| 龙南县| 方正县| 阿瓦提县| 乌什县| 清远市| 葫芦岛市| 旅游| 合水县| 岳西县| 盐源县| 通许县| 景泰县| 成都市| 芜湖市| 安龙县| 尚志市| 江津市| 朝阳县| 桐柏县| 古浪县| 互助| 河北省| 兴城市| 临海市|