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

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

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

    nighty

    折騰的年華
    posts - 37, comments - 143, trackbacks - 0, articles - 0

    保存你的RCP視圖狀態(tài)

    Posted on 2007-10-30 15:51 寒武紀(jì) 閱讀(8681) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): Eclipse

        每當(dāng)做開(kāi)發(fā)的時(shí)候,你有可能在一次調(diào)試程序的過(guò)程中打開(kāi)很多個(gè)編輯器,或是對(duì)Eclipse默認(rèn)的視圖布局不滿(mǎn)意,手工作了一些調(diào)整。如果在工作的過(guò)程你因?yàn)橛惺码x開(kāi)或是不小心把Eclipse關(guān)掉了,不用擔(dān)心,在你下次打開(kāi)的時(shí)候,Eclipse仍然會(huì)為您記住上次的工作場(chǎng)景。下面是一個(gè)例子場(chǎng)景:
        
          Eclipse會(huì)記住“包資源管理器”的當(dāng)前展開(kāi)元素、被選中元素、視圖大小、位置、過(guò)濾、排序等狀態(tài)。不止于視圖和編輯器,Eclipse還提供了對(duì)全局狀態(tài)的持久化機(jī)制。包括向?qū)В珹ction等
          GUI狀態(tài)持久化不是必須的,只是一種可選的增強(qiáng)功能。一個(gè)完整的復(fù)雜的產(chǎn)品,特別是針對(duì)IDE類(lèi)型的RCP,這個(gè)特征就顯得比較人性化。
          下面介紹一些個(gè)人的實(shí)踐心得,愿大家有所收獲,主要是針對(duì)視圖(IViewPart)。
           一般視圖都是繼承自ViewPart類(lèi)或是實(shí)現(xiàn)IViewPart接口,在ViewPart中可以發(fā)現(xiàn)有
            

    /**
         * Initializes this view with the given view site.  A memento is passed to
         * the view which contains a snapshot of the views state from a previous
         * session.  Where possible, the view should try to recreate that state
         * within the part controls.
         * <p>
         * This method is automatically called by the workbench shortly after the part 
         * is instantiated.  It marks the start of the views's lifecycle. Clients must 
         * not call this method.
         * </p>
         *
         * 
    @param site the view site
         * 
    @param memento the IViewPart state or null if there is no previous saved state
         * 
    @exception PartInitException if this view was not initialized successfully
         
    */

        
    public void init(IViewSite site, IMemento memento) throws PartInitException;

        
    /**
         * Saves the object state within a memento.
         *
         * 
    @param memento a memento to receive the object state
         
    */

        
    public void saveState(IMemento memento);

        這二個(gè)方法就是實(shí)現(xiàn)界面狀態(tài)持久化的關(guān)鍵,注意saveState方法是在IPersistable接口中定義的。這些我們暫時(shí)忽略,主要是看如何使用這些機(jī)制。
        如果去看JDT的實(shí)現(xiàn)或是org.eclipse.ui.ide一些視圖的實(shí)現(xiàn),你可以發(fā)現(xiàn)一些比較常用的實(shí)現(xiàn)形式。下面先看一段示例

        private IMemento fmemento;
        
        
    /* 視圖持久化狀態(tài)標(biāo)識(shí) */
        
    private static final String TAG_SELECTION = "selection"//$NON-NLS-1$
        private static final String TAG_EXPANDED = "expanded"//$NON-NLS-1$
        private static final String TAG_ELEMENT = "element";//$NON-NLS-1$
        private static final String TAG_PATH = "path"//$NON-NLS-1$
        
        
    public void init(IViewSite site, IMemento memento) throws PartInitException {
            
    super.init(site, memento);
            
    this.fmemento = memento;
        }

        這是重寫(xiě)你自定義視圖的init方法,定義一個(gè)全局的IMemento對(duì)象,初始化的時(shí)候?yàn)樗x值。并定義一系列的標(biāo)識(shí)常量,用來(lái)表示你要保存的數(shù)據(jù)的標(biāo)識(shí)。這一點(diǎn)與IDialogSettings是一致的。
        下面是保存視圖實(shí)現(xiàn)代碼,如果你第一次接觸可能有點(diǎn)暈,不過(guò)沒(méi)關(guān)系,熟悉了以后你會(huì)發(fā)現(xiàn)Eclipse的內(nèi)部實(shí)現(xiàn)也是類(lèi)似的。下面的代碼就是從Eclipse里面改過(guò)來(lái)的。

    /**
         * 保存視圖狀態(tài)
         * <p>在此沒(méi)有過(guò)濾和排序功能,所以只要保存展開(kāi)節(jié)點(diǎn)的狀態(tài)和選中節(jié)點(diǎn)的狀態(tài)就夠了</p>
         
    */

        
    public void saveState(IMemento memento) {
            System.out.println(
    "保存視圖");
             
    //save visible expanded elements
            Object expandedElements[] = viewer.getVisibleExpandedElements();
            
    if (expandedElements.length > 0{
                IMemento expandedMem 
    = memento.createChild(TAG_EXPANDED);
                
    for (int i = 0; i < expandedElements.length; i++{
                    
    if (expandedElements[i] instanceof ITestNode) {
                        System.out.println(
    "展開(kāi)元素 " +((ITestNode)expandedElements[i]).getPath());
                        IMemento elementMem 
    = expandedMem
                                .createChild(TAG_ELEMENT);
                        elementMem.putString(TAG_PATH,
                                ((ITestNode) expandedElements[i]).getPath());
                    }

                }

            }

            
    //save selection
            Object elements[] = ((IStructuredSelection) viewer.getSelection())
                    .toArray();
            
    if (elements.length > 0{
                IMemento selectionMem 
    = memento.createChild(TAG_SELECTION);
                
    for (int i = 0; i < elements.length; i++{
                    
    if (elements[i] instanceof ITestNode) {
                        System.out.println(
    "選中元素 " +((ITestNode)elements[i]).getPath());
                        IMemento elementMem 
    = selectionMem
                                .createChild(TAG_ELEMENT);
                        elementMem.putString(TAG_PATH,
                                ((ITestNode) elements[i]).getPath());
                    }

                }

            }

            System.out.println(
    "保存視圖完成");
        }

        要保存的數(shù)據(jù)是key--value形式,可以定義Boolean Integer Float String等基本類(lèi)型對(duì)應(yīng)的值,這些值就以key--value形式持久化到文件中。
        上面的實(shí)現(xiàn)內(nèi)容其實(shí)就是把視圖中的樹(shù)組件中的二部分狀態(tài)轉(zhuǎn)換成數(shù)據(jù):展開(kāi)元素和被選中元素。通過(guò)把它們轉(zhuǎn)換成String類(lèi)型(其實(shí)就是樹(shù)路徑)保存起來(lái)。IMemento的具體用法請(qǐng)查找Eclipse幫助文檔。
        完成了保存,下面我們看如何重新把數(shù)據(jù)取出來(lái),使得打開(kāi)的時(shí)候還原之前關(guān)閉時(shí)的狀態(tài)。
        init()方法調(diào)用的時(shí)候界面控件是還沒(méi)有被創(chuàng)建的,所以不能在init()方法中添加還原的方法,應(yīng)用在控件都創(chuàng)建完成后還原。
        

    /**
         * 創(chuàng)建視圖的內(nèi)容面板
         
    */

        
    public void createPartControl(Composite parent) {
     ..
     
    if (fmemento != null{
                System.out.println(
    "開(kāi)始還原");
                restoreState(fmemento);
            }

            fmemento 
    = null;
     ..
    }

        完成控件創(chuàng)建后就調(diào)用restoreState方法,這是我們自定義的用于還原視圖狀態(tài)的方法。下面看一下,內(nèi)容基本上就是saveState方法的逆向。

        /**
         * 還原視圖的狀態(tài)
         * 
    @param memento
         
    */

        
    private void restoreState(IMemento memento) {
            System.out.println(
    "還原視圖");
            WorkSpaceNode wsn 
    = (WorkSpaceNode)viewer.getInput();
            IMemento childMem 
    = memento.getChild(TAG_EXPANDED);
            
    if (childMem != null{
                ArrayList elements 
    = new ArrayList();
                IMemento[] elementMem 
    = childMem.getChildren(TAG_ELEMENT);
                
    for (int i = 0; i < elementMem.length; i++{
                    System.out.println(
    "還原展開(kāi)路徑 " + elementMem[i].getString(TAG_PATH));
                    Object element 
    = NodeUtil.findNodeByPath(elementMem[i]
                            .getString(TAG_PATH), wsn);
                    System.out.println(
    "還原展開(kāi)節(jié)點(diǎn) " + element);
                    
    if (element != null{
                        elements.add(element);
                    }

                }

                viewer.setExpandedElements(elements.toArray());
            }

            childMem 
    = memento.getChild(TAG_SELECTION);
            
    if (childMem != null{
                ArrayList list 
    = new ArrayList();
                IMemento[] elementMem 
    = childMem.getChildren(TAG_ELEMENT);
                
    for (int i = 0; i < elementMem.length; i++{
                    Object element 
    = NodeUtil.findNodeByPath(elementMem[i]
                            .getString(TAG_PATH), wsn);
                    
    if (element != null{
                        list.add(element);
                    }

                }

                viewer.setSelection(
    new StructuredSelection(list));
            }

            System.out.println(
    "還原視圖完成");
        }

        這些工作就可以完成視圖狀態(tài)的保存與還原,還有一個(gè)特別要注意的地方,你必須對(duì)插件的WorkbenchAdvisor類(lèi)的public void initialize(IWorkbenchConfigurer configurer)方法進(jìn)行重寫(xiě),添加configurer.setSaveAndRestore(true);這個(gè)方法就可以打開(kāi)保存機(jī)制。如果沒(méi)有這個(gè)步驟,上面的工作不會(huì)起任何效果。
        GUI狀態(tài)的持久化都保存在運(yùn)行時(shí)生成的.metadata\.plugins目錄下的xml文件,你可以手動(dòng)去打開(kāi)這些文件查看數(shù)據(jù)結(jié)果是否跟你預(yù)期的一樣。IEditorPart以及Perspective和其它的全局信息持久化的也是同樣的原理。只是復(fù)雜度不一樣。建議可以查看org.eclipse.ui.ide中的實(shí)現(xiàn)原理。

     



    剛進(jìn)場(chǎng)的時(shí)候戲就落幕
    主站蜘蛛池模板: 亚洲码和欧洲码一码二码三码| 亚洲欧美日韩中文二区| 嘿嘿嘿视频免费网站在线观看| 久久aⅴ免费观看| 亚洲国产精品一区二区九九| 成人精品国产亚洲欧洲| 亚洲日韩中文无码久久| 一区二区无码免费视频网站 | 亚洲欧洲国产综合AV无码久久| 日韩精品电影一区亚洲| 久久黄色免费网站| 亚洲AV成人无码久久精品老人| 成年女人午夜毛片免费视频| 亚洲精品无码不卡在线播放| 亚洲精品亚洲人成人网| 午夜免费福利在线| 99精品热线在线观看免费视频| 亚洲天堂一区二区三区四区| 亚洲va中文字幕无码| 亚洲第一成年免费网站| 中文字幕日本人妻久久久免费| 色欲色欲天天天www亚洲伊| 国产在线ts人妖免费视频| 久久水蜜桃亚洲AV无码精品| 久久亚洲私人国产精品| 亚洲无线观看国产精品| 免费日韩在线视频| 亚洲阿v天堂在线2017免费 | AAAAA级少妇高潮大片免费看| 亚洲三级在线观看| 亚洲人成电影福利在线播放| 亚洲精品成人久久久| 狠狠久久永久免费观看| 国产精品久久久久久久久免费| 中文字幕不卡免费高清视频| 黄色网址大全免费| 久久亚洲欧美国产精品| 国产亚洲福利在线视频| 亚洲国产情侣一区二区三区| 日本一区二区三区免费高清| 精品一区二区三区免费毛片爱|