<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    kermart

    k

     

    分層Pane結構與Swing組件高級特性的實現

      這個題目起的有點難懂,但也實在想不出更好的題目來。所謂分層Pane結構是指JFrame/JApplet/JDialog等Swing頂層容器的JRootPane/JLayeredPane/GlassPane/ContentPane結構。所謂Swing組件高級特性其實是指某些組件的特殊功能的實現,比如彈出菜單、Tooltip、JComboBox的下拉窗口、Drag and Drop實現、Docking Pallete窗口等等。這些特性同普通組件不同,它們往往需要動態的變化、覆蓋其他組件,它們之間存在一定層次關系。那么Swing中是怎么樣實現這些功能呢?
      一直以來想寫一篇文章來描述這個關鍵結構,但每次總被自己的語言表達能力所限制。Swing這個精巧結構是我嘆服的原因之一。雖然一般的GUI系統設計原理我都知道,但是細節如此處精細卻不是一開始就能清楚的。我在2000年以前曾經寫過大量基于AWT Canvas的自定義組件,當時認為Swing的自定義組件也不過如此,原理不過也是給我一個刷子,我給你畫出來。但是上述所說的這些特性,卻從來沒能實現過。我想過很多方法,做過很多實驗,但終究沒有想透這一層。之后某次偶然機會,看到了下面這張著名的圖,使我豁然開朗。讓我又一次理解了創新需要跳出舊的思維模式勇氣和智慧。

      簡單來說Swing中這些頂層容器的多Pane結構是實現這些特性的基礎。這些Pane實際是一些特殊的JComponent,它們之間存在包含被包含、覆蓋被覆蓋的樹狀多層次結構。我重新畫了上面這張圖,使得其更具體、更直觀,更容易理解些:

    其實有了這張圖,加上圖形系統中Z-order的概念,就不難理解并實現上面提到的特性。Z-order概念和圖形學中Z深度是一致的。離觀察點近的物體總是會遮擋離觀察點遠的物體。物體所在法平面離觀察點的距離就是所謂Z深度。Swing中通過先畫出Z-order遠(小)的組件,再畫Z-order近(大)的組件的方法實現組件之間的遮擋關系。每個組件所在平面的都有一個數字描述其位置,這個位置同三維坐標系中的Z軸類似,離觀察者越近,坐標越大:

      Swing的頂層容器都包含有一個JRootPane,該JRootPane是一切Swing組件起點。JRootPane中包含了一個JLayeredPane和一個GlassPane。GlassPane和JLayeredPane都是充滿JRootPane的。GlassPane缺省情況下是不可見的,因此我們看到都是JLayeredPane。GlassPane如果是可見的,它Z-order大于任何其他組件,因此它會覆蓋住整個窗口,使得所有的鼠標事件都被它截獲。另外通常可見情況下它是透明的,因此你能仍然看到JLayeredPane上面的一切,但是JLayeredPane上面的組件都得不到鼠標事件。
    GlassPane這個奇怪的組件主要是用來實現Drag & Drop以及跨組件渲染用的。NetBeans和Eclipse中哪種常見的Docking Frame的實現就和這種組件相關。這些工程、文件、源代碼的窗口其實不過是普通的Swing組件,它們本身并不能實現這種拖拽功能。鼠標在它們上面標題欄區域按下之后,標題欄組件會檢測到這種事件,經過粘連性判斷后,如果發現這些鼠標事件目的是拖拽窗口,這種Docking系統就會將拖拽區域(即所謂的ClientArea)的GlassPane設置為可見,于是下面的一些列拖拽鼠標事件就被這個GlassPane所接管了過去。GlassPane是覆蓋于應用程序ClientArea的透明組件,它處理這些事件時計算出當前鼠標位置所蘊含著的拖拽動作,并根據這些動作畫出相應的焦點矩形。NetBeans的Docking Framework一個拖拽過程如下圖所示.注意GlassPane是背景透明的,所以可以在上面畫背景透明的焦點矩形:

      JLayeredPane是實現彈出式窗口或類似Pallete浮動窗口的主要組件。如同它的名字一樣,它將自己的內部結構也分成許多亞層。在使用它的add(Component, Object)方法加入組件時,第二個參數是一個Integer值,這個值決定了加入的層。這個值相當于前面所說的Z-order值。目前主要有下面幾個預定義值:
    public final static Integer DEFAULT_LAYER = new Integer(0);
    這層加入的缺省層。
      public final static Integer PALETTE_LAYER = new Integer(100);
    這層是定義Palette窗口的層。那種浮動選項窗口屬于這一層。
      public final static Integer MODAL_LAYER = new Integer(200);
    這層是模態對話框的層。這個模態對話框應該是指JInternalFrame的模態對話框,而不是JDialog。
      public final static Integer POPUP_LAYER = new Integer(300);
    這層是菜單、下拉框窗口、Tooltip等窗口浮動的層。
      public final static Integer DRAG_LAYER = new Integer(400);
    這一層是拖拽層,組件可以在這一層被托拽。
      public final static Integer FRAME_CONTENT_LAYER = new Integer(-30000);
    這一層是ContentPane和MenuBar所在的層。注意它非常小,前面所有層的組件都會覆蓋這一層的組件。我們知道ContentPane是所有應用程序組件所在的地方。
      JLayeredPane直接包含有ContentPane組件。應用程序如果定了MenuBar,JLayeredPane還包含MenuBar。注意JLayeredPane本身沒有布局管理器,它對組件的布局是由它的父容器JRootPane的布局管理器RootLayout來完成的。簡單來說,所在層數值小的組件有可能被高層組件所覆蓋。Swing將不同類型的組件放置在不同層面上,就實現了文章一開始提到的特性:菜單、浮動窗口、下拉框窗口和Tooltip等。當然這些窗口有可能不是JLayeredPane上的輕量級Swing組件,當它們的邊界超過頂層容器的窗口時,這些窗口的就變成了重量級AWT窗口。這在上一篇文章《如何混排Swing和AWT組件中已經提到過。
      下面是這些Pane組件之間的樹狀包含關系圖:

      本文的目的是講述Swing的這種組件層次結構,并不是講述如何使用JLayeredPane和GlassPane來實現某中特殊的功能。如果需要學習如何使用它們實現某些特殊效果,Java Tutorial的Swing部分提供了詳盡的編程資料。Java Tutorial的Swing部分編程在:
      如何使用RootPane、GlassPane和JLayeredPane分別見下面的章節:

    posted on 2012-07-26 11:21 kermart 閱讀(1242) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     

    導航

    統計

    常用鏈接

    留言簿

    隨筆檔案

    收藏夾

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲毛片在线观看| 亚洲精品高清久久| 日本系列1页亚洲系列| 日本媚薬痉挛在线观看免费| 亚洲一级毛片免观看| 又黄又爽又成人免费视频| 亚洲成AV人片久久| 毛片A级毛片免费播放| 亚洲中文字幕无码中文| 男女啪啪永久免费观看网站| 亚洲日韩精品无码专区| 国产精品va无码免费麻豆| 免费毛片毛片网址| 国产亚洲综合一区柠檬导航| 4399影视免费观看高清直播| 亚洲免费视频网址| 国产在线观看免费视频播放器| 国产亚洲蜜芽精品久久| 亚洲精品字幕在线观看| aⅴ免费在线观看| 亚洲av日韩av永久无码电影| 夜色阁亚洲一区二区三区| 高清永久免费观看| 亚洲婷婷综合色高清在线| 小小影视日本动漫观看免费| 成人特级毛片69免费观看| 亚洲avav天堂av在线不卡| 野花高清在线电影观看免费视频| 久久亚洲中文字幕无码| 亚洲中文字幕日产乱码高清app | 波多野结衣久久高清免费| 青娱乐在线视频免费观看| 亚洲AV永久青草无码精品| 啦啦啦中文在线观看电视剧免费版 | 国产香蕉免费精品视频| 国产成人综合亚洲| 亚洲成色999久久网站| 国产小视频在线观看免费| 蜜桃成人无码区免费视频网站| 色偷偷噜噜噜亚洲男人| 亚洲AV无码专区国产乱码电影|