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

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

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

    Read Sean

    Read me, read Sean.
    posts - 508, comments - 655, trackbacks - 9, articles - 4

    [Eclipse筆記]在SWT中有效的管理圖形系統資源

    Posted on 2005-03-20 17:11 laogao 閱讀(769) 評論(0)  編輯  收藏 所屬分類: On Java 、On Eclipse

    本文部分內容和靈感來自eclipse.org網站,特此聲明。更多內容,請參考:

    http://eclipse.org/articles/Article-SWT-Design-2/SWT-Design-2.html

     

    由于SWT直接跟操作系統打交道,所以我們需要在處理系統的圖形資源時格外小心,以免不必要的資源泄漏。所幸SWT提供了很好的資源管理機制,我們絕大多數情況下需要做的只是確保兩條原則:

    第一條原則 誰分配誰銷毀

    第二條原則 父控件銷毀的同時銷毀子控件

     

    下面我們分別來看一看這兩條在實際中是如何體現的。

    先看第一條原則。乍一看這似乎是廢話,但是在實際中往往并非那么簡單。首先,構造方法不等于分配資源,實際上分配資源可以發生在一個類中的任何地方以及一個對象生命周期的任何時候,只要你的代碼告訴操作系統這樣做。你必須保證所有由你分配的資源當你不再使用時調用其dispose()方法;同時你也必須保證所有不是由你分配的資源不要隨便調用其dispose()方法,否則很可能會影響到實際分配的那段相關代碼的正常工作。好消息是,為了明確和簡化這第一條原則所規定的分工,SWT在設計之初就確定下來,所有基于系統資源的SWT類都在其構造方法中完成所有所需的資源分配,在其他方法中則沒有任何分配系統資源的動作,所以我們可以幸運的這樣看待SWT的資源管理:如果你調用了某個SWT類的構造方法,那么就由你來調用其dispose()方法釋放資源;如果你沒有調用某個SWT類的構造方法,即便你使用了這個類的實例,也不應該由你來調用其dispose()方法。就是這么明確。

    比方講,你new了一個Font對象,那么當你不再需要它時,就應該調用dispose();如果你通過某個控件的getFont()方法取得一個Font對象并使用后,你不應該去銷毀它,而應該交給那個具體的控件去處理。

    對于第二條原則,SWT有一個很好的機制去支持它,那就是,所有的SWT控件,具體講,Composite類及其子類的實例,都必須有一個父控件,這個父控件的引用在子控件的構造方法中被傳入。需要注意的是,所有這些控件的不帶參數的構造方法都只有默認訪問級別,于是我們不能在自己的SWT程序中直接調用這樣的默認構造方法而只能提供一個父控件的引用,而在Widget類(Composit的父類)的帶參數構造方法中,它會調用如下方法:

    void checkParent (Widget parent) {
           
    if (parent == null) error (SWT.ERROR_NULL_ARGUMENT);
           parent.checkWidget ();
    }

    進而:

    protected void checkWidget () {
           Display display 
    = this.display;
           
    if (display == null) error (SWT.ERROR_WIDGET_DISPOSED);
           
    if (display.thread != Thread.currentThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
           
    if ((state & DISPOSED) != 0) error (SWT.ERROR_WIDGET_DISPOSED);
    }

    這樣的檢查保證了任何控件在創建時都有父控件。當我們調用某個Compositedispose()方法時,它會調用:

    void releaseChildren () {
           Control [] children 
    = _getChildren ();
           
    for (int i=0; i<children.length; i++{
                  Control child 
    = children [i];
                  
    if (!child.isDisposed ()) child.releaseResources ();
           }

    }

    其中的_getChildren()方法通過OS對象的方法遍歷控件的子控件,然后匯總到一起分別調用releaseResources()方法釋放控件和句柄。

    回到上次的SimplestSWT的例子:


    package sean.test.swt;

    import org.eclipse.swt.widgets.Display;
    import org.eclipse.swt.widgets.Shell;

    public class SimplestSWT {

        
    public static void main(String[] args) {
            Display display 
    = new Display();
            Shell shell 
    = new Shell(display);
            shell.pack();
            shell.open();
            
    while (!shell.isDisposed()) {
                
    if (!display.readAndDispatch()) {
                    display.sleep();
                }

            }

            display.dispose();
        }


    }

     

    這當中,Display是一個頂層的設備,它繼承自Device類,而Device類實現了Drawable接口。Shell的父類是Decoration,而Decoration繼承自CanvasCanvas繼承自Composite,最終這條繼承鏈一直連到Widget類。我們在創建Shell示例的時候,需要告訴構造方法它的父控件是什么,在這里就是display。于是當我們最后調用display.dispose()時,雖然我們沒有明確寫shell.dispose(),我們的Shell實例也隨之銷毀了。

    這就是SWT的資源管理機制,稍有例外的是MenuItemsetMenu()方法和ControlsetMenu()方法,它們通過顯式調用setMenu的方式注冊自己的父控件。

     

    主站蜘蛛池模板: 亚洲AV综合色区无码一区| 豆国产96在线|亚洲| 德国女人一级毛片免费| 免费国产在线精品一区| 亚洲成人在线网站| 国产高清在线精品免费软件 | 直接进入免费看黄的网站| 国产精品亚洲高清一区二区| **俄罗斯毛片免费| 黄页免费视频播放在线播放| 亚洲人成网站影音先锋播放| 国产一区在线观看免费| 99re这里有免费视频精品| 理论片在线观看免费| 亚洲国产精品白丝在线观看| www.91亚洲| 日本一区二区三区免费高清| 中文字幕永久免费| 亚洲欧美熟妇综合久久久久| 亚洲AV午夜成人片| 亚洲高清无码综合性爱视频| 久久久久国色AV免费观看性色| 人妻免费一区二区三区最新| 在线视频亚洲一区| 亚洲乱码一二三四五六区| 亚洲国产婷婷六月丁香| 亚洲国产一区视频| 午夜网站免费版在线观看| 在线观看永久免费| 大地资源中文在线观看免费版| 色视频在线观看免费| 亚洲精品无码久久久久APP| 亚洲精品视频在线播放| 久久精品国产亚洲av四虎| 亚洲精品国产精品国自产观看| 成人午夜大片免费7777| 免费黄色福利视频| 久久不见久久见免费视频7| 国产偷伦视频免费观看| 国产精品极品美女自在线观看免费| 亚洲av无码专区在线电影 |