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

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

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

    Picses' sky

    Picses' sky
    posts - 43, comments - 29, trackbacks - 0, articles - 24

    [翻譯]創建一個彈出通知部件

    Posted on 2009-07-02 15:14 Matthew Chen 閱讀(1270) 評論(1)  編輯  收藏 所屬分類: Java SE

    在本文中我將解釋如何創建一個自定義的部件,它在屏幕右下角顯示一個彈出通知對話框(Windows中通常是在工具欄上面) 。 以下是完成時它的樣子:

    Example Image

    我們可以在組件上繪制一切來定制我們所需要的各種控制,但這篇文章的目的在于使用基本的SWT組件在一個普通的Shell中實現比典型SWT Shell更加美觀的效果。

    (注意,僅在Windows上進行過測試,在其它平臺上可能有所不同) 。


    Shell

    我們想要一個shell停留在我們的程序的上方(但不是所有程序的上方),但不獲取焦點、顯示在你的任務管理器或是影響用戶關注的對象。 我們也不使用"trim"來給Shell加邊框而是繪制自定義的邊框。我們所有的要求都可以通過SWT的flags參數方便的創建。我們可以如下創建Shell:


    
    
    1. _shell = new Shell(Display.getDefault().getActiveShell(), SWT.NO_FOCUS | SWT.NO_TRIM); 

    由于我們的SWT組件在shell內部并且我們打算對shell本身使用漸變背景,所有的組件都必須是透明的。通過在shell上設置背景色模式為SWT.INHERIT_DEFAULT來實現。它告訴組建繼承它們父組件的背景色。在創建shell之后我們簡單調用:

    
    
    1. _shell.setBackgroundMode(SWT.INHERIT_DEFAULT); 

    那么如何在shell上得到漸變的背景色呢?默認方式下是不支持的。你可以設置一個前景色和一個背景色但也就只能如此了。技巧是我們使用我們想要的顏色繪制一個圖像來作為shell的背景。為了在合適的時間做到這一點,我們監聽shell上的SWT.Resize事件,代碼如下;

    
    
    1. _shell.addListener(SWT.Resize, new Listener() { 
    2.     @Override 
    3.     public void handleEvent(Event e) { 
    4.     try { 
    5.         // get the size of the drawing area 
    6.         Rectangle rect = _shell.getClientArea(); 
    7.         // create a new image with that size 
    8.         Image newImage = new Image(Display.getDefault(), Math.max(1, rect.width), rect.height); 
    9.         // create a GC object we can use to draw with 
    10.         GC gc = new GC(newImage); 
    11.  
    12.         // fill background 
    13.         gc.setForeground(_bgFgGradient); 
    14.         gc.setBackground(_bgBgGradient); 
    15.         gc.fillGradientRectangle(rect.x, rect.y, rect.width, rect.height, true); 
    16.  
    17.         // draw shell edge 
    18.         gc.setLineWidth(2); 
    19.         gc.setForeground(_borderColor); 
    20.         gc.drawRectangle(rect.x + 1, rect.y + 1, rect.width - 2, rect.height - 2); 
    21.         // remember to dipose the GC object! 
    22.         gc.dispose(); 
    23.  
    24.         // now set the background image on the shell 
    25.         _shell.setBackgroundImage(newImage); 
    26.  
    27.         // remember/dispose old used iamge 
    28.         if (_oldImage != null) { 
    29.         _oldImage.dispose(); 
    30.         } 
    31.         _oldImage = newImage; 
    32.     } 
    33.     catch (Exception err) { 
    34.         err.printStackTrace(); 
    35.     } 
    36.     } 
    37. }); 

    內容

    我們的shell由3個部分組成,圖片在左上角(一個普通的CLabel ) 。 然后一個包含標題文字的標簽(也是CLabel ) ,最后一個標簽顯示我們的信息(一個普通的Label) 。 我們最后使用一個Label而不是CLabel來支持比CLabel更佳的斷行和多行效果。 您當然也可以使用幾乎任何你想要的組建。 以下是用線框分割的每個標簽:

    tray_popup_example_lines

    我們使用邊緣間隔5px的GridLayout(除頂部)除此之外沒有特別的效果創建,所以我就不在這里寫出代碼了(在底部供下載) 。

    一些眼球效果-凋謝

    在3.4的SWT中Shells支持alpha值設置,所以我們將以此來實現更美觀的"呈現"和"消失",所有我們所需要做的就是在一個線程中循環增加/減少shell的alpha通道值來實現shell的淡入和淡出消失。我們必須在Display線程上來做這些操作,為此提供了一個runnable讓Display對象以給定的時間間隔運行

    在多線程的環境下記得始終檢查shell是否已經被銷毀了。當淡入顯示完成后,我們希望shell顯示一定時間然后消失掉,所以基本的流程鏈是

    • 創建shell
    • 淡入shell
    • 可的X秒
    • 淡出shell
    • 銷毀shell

    所有的這些定時器或多或少就如編碼中的那樣,所以我僅提供了一個例子其余的可以參考下載中的完整代碼方面,我們需要解釋一些全局的變量

    • FADE_IN_STEP是每次迭代中alpha值的增量。
    • FINAL_ALPHA是當shell保持可見時的alpha值。一定透明度的shell將提供更佳的效果,所以默認該值是225(255則為一個完全[不透明]的shell) 。
    • FADE_TIMER是alpha變化的時間間隔。當shell達到它的最大alpha值時調用startTimer()方法,這是一個線程,休眠若干秒,然后調用fadeOut()方法。
    
    
    1. private static void fadeIn(final Shell _shell) { 
    2.     Runnable run = new Runnable() { 
    3.  
    4.         @Override 
    5.         public void run() { 
    6.             try { 
    7.                 if (_shell == null || _shell.isDisposed()) { return; } 
    8.  
    9.                 int cur = _shell.getAlpha(); 
    10.                 cur += FADE_IN_STEP; 
    11.  
    12.                 if (cur > FINAL_ALPHA) { 
    13.                     _shell.setAlpha(FINAL_ALPHA); 
    14.                     startTimer(_shell); 
    15.                     return
    16.                 } 
    17.  
    18.                 _shell.setAlpha(cur); 
    19.                 Display.getDefault().timerExec(FADE_TIMER, this); 
    20.             } 
    21.             catch (Exception err) { 
    22.                 err.printStackTrace(); 
    23.             } 
    24.         } 
    25.  
    26.     }; 
    27.     Display.getDefault().timerExec(FADE_TIMER, run); 

    堆疊的通知

    最后我們要支持的,是堆疊通知。 假設我們的通知shell的整個生命周期是5秒,如果有額外的通知在第一個通知關閉之前到達呢?我們可以銷毀第一個通知,并以后者取代,但更美觀的方法是簡單地將前者升高,讓后者顯示在前者的下方。效果如下(截屏時之前的shell開始淡出,所以它們有更高的透明度) :

    tray_stacked

    實現這一效果是相當簡單的。 每次通知shell被打開,我們在靜態的shell數組中保留一個引用。當它淡出(并銷毀)后,從該列表中移除。因此,當一個新的shell到來后我們查看當前數組中已經存在的元素并對每一個舊的shell-heightOfNewNotificationShell 因此,舊的shell上移以騰出空間,但繼續如前地完成它們的淡入/淡出周期。

    進一步改善

    當然一切都可以做得更加美觀,也許你想要一個“ X ”關閉按鈕,或不同顏色的文字,或圓角邊框。 當前代碼中并沒有實現這些,但為你實現大多數功能避免問題

    另外請注意,我目前使用Display.getDefault().getActiveShell()作為彈出窗口的夫shell。您可能想把它重構為一個永久性的shell以便在任何父shell被銷毀或任何彈出窗被顯示的時候都能使通知被銷毀。

     

    代碼不是十全十美的,卻可以作為構建的基礎(如果你愿意的話) 。

    下載代碼

    我已創建了一個基于Eclipse項目的代碼,ImageCache / FontCache / ColorCache(它們的目的是為了緩存圖片等系統資源)。 還有一個用來存放圖片的jar。 如果你喜歡它們,可以找到更多: Gnome的顏色圖標 。

    請注意您可能需要調整您的CLASSPATH設置的項目,以對應自己的SWT jar所在。

    運行Tester.java然后按下按鈕啟動通知。在前一個通知消失前再次按下隨機圖像將顯示。

    下載代碼

    結論

    希望這可讓您深入了解如何創建“自定義部件” (沒有多少定制繪畫)。 玩得開心!

    Feedback

    # re: [翻譯]創建一個彈出通知部件  回復  更多評論   

    2009-07-03 14:09 by 瑜伽館
    最近正想用,學習啦!
    主站蜘蛛池模板: 亚洲精品在线不卡| 99视频免费播放| 亚洲人xxx日本人18| 亚洲乱码日产一区三区| 热99re久久免费视精品频软件| 99视频免费播放| 国产免费高清69式视频在线观看| 亚洲AV无码专区在线观看成人 | 亚洲色大成网站www久久九| 麻豆亚洲AV永久无码精品久久| 精品亚洲成α人无码成α在线观看| 日本高清免费aaaaa大片视频| 精品国产无限资源免费观看| 永久在线观看免费视频| 免费的黄色网页在线免费观看| 亚洲国产区男人本色在线观看| 亚洲欧洲精品一区二区三区| 久久久青草青青亚洲国产免观| 久久伊人亚洲AV无码网站| 亚洲av高清在线观看一区二区 | 色偷偷亚洲男人天堂| 亚洲欧洲AV无码专区| 狠狠色伊人亚洲综合网站色| 久久狠狠爱亚洲综合影院| 久久精品国产亚洲αv忘忧草| 亚洲精品乱码久久久久久下载| 亚洲AV无码1区2区久久| 亚洲av无码一区二区三区网站| 亚洲无线码在线一区观看| 亚洲午夜久久久影院伊人| 亚洲线精品一区二区三区| 国产亚洲精品精品国产亚洲综合| 亚洲熟伦熟女新五十路熟妇| 国产aa免费视频| 免费在线观看毛片| 亚洲美女在线国产| 国产亚洲色视频在线| 国产亚洲精品精华液| 亚洲成AV人片在线观看无码| 色播亚洲视频在线观看| 亚洲综合无码一区二区三区|