Java桌面技術(shù)

          Java Desktop Technology

          常用鏈接

          統(tǒng)計(jì)

          友情連接

          最新評(píng)論

          打造專業(yè)外觀-二

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

          二、改變大小
          添加如下變量聲名
          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;
            }
          其原理同上。
          這個(gè)時(shí)候可以改變尺寸了,再添加如下功能畫龍點(diǎn)睛。
          private Cursor seCursor = new Cursor(getDisplay(), SWT.CURSOR_SIZESE);

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

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

          評(píng)論

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

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

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

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

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

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

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

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

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

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

          @Matthew Chen
          如果C水平足夠強(qiáng)的話,完全可以彌補(bǔ)AWT SWT處理半透明等能力的不足,jna就是C。但是Java開發(fā)員當(dāng)然期望這一切集成在Java中,Sun之所以計(jì)劃在JDK1.7中實(shí)現(xiàn)這一功能,Vista的刺激是很重要的原因,AWT要實(shí)現(xiàn)不規(guī)則窗體、半透明窗體不是那么容易,原因不在AWT與技術(shù)難度,是因?yàn)榻涌诘弥匦聦?,還要考慮跨平臺(tái)和向前兼容,即使在JDK中有對(duì)應(yīng)的功能,對(duì)于某些不支持透明的OS也無能為力。Sun公司AWT研發(fā)在俄羅斯,Swing研發(fā)在美國,彼此的協(xié)商也是一定問題,為蘇聯(lián)老大哥祈禱吧。  回復(fù)  更多評(píng)論   

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

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

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

          精彩  回復(fù)  更多評(píng)論   

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

          >>> 透明窗格
          ----------------------------------------------------------------
          不通過JNI,透明窗格根本沒法實(shí)現(xiàn),因?yàn)槟鞘谴翱谧酉到y(tǒng)的一個(gè)特性。
          窗口子系統(tǒng)不支持的話,誰也沒則。 Windows 2000就不支持, 據(jù)說
          Linux采用的X Window也不支持。 最早是macosx實(shí)現(xiàn)的,Microsoft直到
          XP才有。SWT沒有加入這個(gè)功能,可能是因?yàn)槭艿教嘤嘘P(guān)平臺(tái)之間差異性
          的批評(píng),和不支持的平臺(tái)太多也有關(guān)。其實(shí)完全可以提供,如果平臺(tái)不支持就忽略。像SWT一貫的做法,我覺得挺好。

          可以模擬,像Matthew Chen說的是一種方法,缺點(diǎn)是得啟動(dòng)一個(gè)Timer。

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


          不然就得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。 就把一個(gè)不透明的Shell,改成透明度為alpha
          的Shell了, alpha在0到256之間, 0是全透明。3個(gè)C函數(shù)SWT的
          OS都已經(jīng)做好對(duì)應(yīng),省了很多麻煩。

          懶得寫文章,就接LZ的帖子和大家分享些經(jīng)驗(yàn)了。
            回復(fù)  更多評(píng)論   

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

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

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

          是啊, org.eclipse.swt.internal.win32.OS是SWT的一個(gè)非API類。當(dāng)然你得用windows的SWT版本。我是在3.4M2下試的,好像不是新加上的,3.3應(yīng)該早就有了  回復(fù)  更多評(píng)論   

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

          太棒了。正是我所想要的。學(xué)習(xí)研究中  回復(fù)  更多評(píng)論   

          TWaver中文社區(qū)
          主站蜘蛛池模板: 临江市| 吉木乃县| 浑源县| 大冶市| 博罗县| 北海市| 旅游| 铅山县| 石柱| 抚远县| 庆元县| 光山县| 田阳县| 师宗县| 扎囊县| 黄陵县| 连南| 长子县| 油尖旺区| 密山市| 河津市| 清河县| 元谋县| 高州市| 文水县| 四川省| 西华县| 墨江| 仙桃市| 托克托县| 尼木县| 扶余县| 鄂州市| 庆城县| 平潭县| 兴业县| 镇远县| 丰宁| 顺平县| 化德县| 芦溪县|