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

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

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

    love fish大鵬一曰同風起,扶搖直上九萬里

    常用鏈接

    統計

    積分與排名

    friends

    link

    最新評論

    保存你的RCP視圖狀態(轉)

    每當做開發的時候,你有可能在一次調試程序的過程中打開很多個編輯器,或是對Eclipse默認的視圖布局不滿意,手工作了一些調整。如果在工作的過程你因為有事離開或是不小心把Eclipse關掉了,不用擔心,在你下次打開的時候,Eclipse仍然會為您記住上次的工作場景。下面是一個例子場景:
        
          Eclipse會記住“包資源管理器”的當前展開元素、被選中元素、視圖大小、位置、過濾、排序等狀態。不止于視圖和編輯器,Eclipse還提供了對全局狀態的持久化機制。包括向導,Action等
          GUI狀態持久化不是必須的,只是一種可選的增強功能。一個完整的復雜的產品,特別是針對IDE類型的RCP,這個特征就顯得比較人性化。
          下面介紹一些個人的實踐心得,愿大家有所收獲,主要是針對視圖(IViewPart)。
           一般視圖都是繼承自ViewPart類或是實現IViewPart接口,在ViewPart中可以發現有
            
    /**
         * 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);

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

        private IMemento fmemento;
        
        
    /* 視圖持久化狀態標識 */
        
    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;
        }

        這是重寫你自定義視圖的init方法,定義一個全局的IMemento對象,初始化的時候為它賦值。并定義一系列的標識常量,用來表示你要保存的數據的標識。這一點與IDialogSettings是一致的。
        下面是保存視圖實現代碼,如果你第一次接觸可能有點暈,不過沒關系,熟悉了以后你會發現Eclipse的內部實現也是類似的。下面的代碼就是從Eclipse里面改過來的。

    /**
         * 保存視圖狀態
         * <p>在此沒有過濾和排序功能,所以只要保存展開節點的狀態和選中節點的狀態就夠了</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(
    "展開元素 " +((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(
    "保存視圖完成");
        }

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

    /**
         * 創建視圖的內容面板
         
    */

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

            fmemento 
    = null;
     ..
    }

        完成控件創建后就調用restoreState方法,這是我們自定義的用于還原視圖狀態的方法。下面看一下,內容基本上就是saveState方法的逆向。

        /**
         * 還原視圖的狀態
         * 
    @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(
    "還原展開路徑 " + elementMem[i].getString(TAG_PATH));
                    Object element 
    = NodeUtil.findNodeByPath(elementMem[i]
                            .getString(TAG_PATH), wsn);
                    System.out.println(
    "還原展開節點 " + 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(
    "還原視圖完成");
        }

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

    posted on 2007-10-31 08:46 liaojiyong 閱讀(1315) 評論(0)  編輯  收藏


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


    網站導航:
     
    主站蜘蛛池模板: 亚洲欧洲国产综合| 搜日本一区二区三区免费高清视频 | 亚洲中文字幕丝袜制服一区| 国内精品免费视频精选在线观看| 国产福利视精品永久免费| 亚洲色大成网站www永久男同| 亚洲日韩在线观看| 91手机看片国产永久免费| 国产天堂亚洲国产碰碰| 久久久久亚洲AV无码专区体验| 国产精品国产自线拍免费软件| 日本亚洲欧洲免费天堂午夜看片女人员 | 青青操视频在线免费观看| 亚洲一卡2卡3卡4卡乱码 在线| 中文字幕亚洲天堂| 69成人免费视频无码专区| 国产免费网站看v片在线| 久久亚洲国产午夜精品理论片| 拍拍拍又黄又爽无挡视频免费| 久久久久亚洲AV无码去区首| 亚洲国产人成中文幕一级二级| h片在线免费观看| 你是我的城池营垒免费看| 亚洲精品理论电影在线观看| 亚洲精品美女久久久久99小说| 天天影院成人免费观看| 国产在线观看xxxx免费| 亚洲精品乱码久久久久久下载| 亚洲Av无码国产情品久久| 在线观看免费视频一区| 亚洲成熟丰满熟妇高潮XXXXX| 亚洲日本香蕉视频| 亚洲欧洲日产国码久在线观看| 亚洲第一黄色网址| 午夜dj免费在线观看| a级毛片视频免费观看| 国产午夜亚洲精品不卡电影| 亚洲一区二区三区国产精华液| 亚洲日韩在线视频| 亚洲一二成人精品区| 亚洲VA成无码人在线观看天堂|