继承PageBookView实现自己的“属性视图”

转载自:http://www.cnblogs.com/bjzhanghao/archive/2007/07/23/828850.html

 

很多Eclipse应用程序在提供一个Editor的同时还提供一些View,这些View监视Editor的Selection,提供一些上下文 相关的信息。Eclipse自带的PropertySheet(属性视图)就是这样一个例子,Outline(大纲视图)也是如此,从功能上看,不妨把这 类用途的视图称为“广义的属性视图”。

以前我都是直接继承ViewPart来实现自己的属性视图的,但我发现要花不少功夫在处理View与Editor的协调上。例如当Editor被关 闭时,View里的信息也应该隐藏,切换Editor时也需要进行处理,等等。最近看一个项目的代码时发现他们是继承 org.eclipse.ui.part.PageBookView来实现同样功能的,就像PropertySheet所做的一样,效果很不错,而且需要 自己写的代码量不是很多,因为PageBookView里已经帮助处理了以上提到的大部分功能。因此这里介绍一下使用PageBookView的方法供大 家参考。

顾名思义,PageBookView是这样一种View,它就像一本书,里面可以容纳多个Page,但同一时间只给用户显示一个Page。 PageBookView负责根据当前活动的WorkbenchPart切换到合适的Page,实际显示的内容主要由Page提供,这些Page一般是通 过WorkbenchPart的getAdapter()方法提供的。

继承PageBookView实现自己的属性视图时,PageBookView子类的实现几乎是固定的,如果你的View与 WorkbenchPart里的Selection有关(上下文敏感),则继承PageBookView的时候应顺便实现 ISelectionListener,然后在init()方法里注册自己为WorkbenchPage的选择监听器,并在 selectionChanged()方法里把事件转发给当前显示的Page,下面的代码是一个典型的上下文敏感的PageBookView子类:

 

import  org.eclipse.jface.viewers.ISelection;
import  org.eclipse.swt.widgets.Composite;
import  org.eclipse.ui.IEditorPart;
import  org.eclipse.ui.ISelectionListener;
import  org.eclipse.ui.IViewSite;
import  org.eclipse.ui.IWorkbenchPage;
import  org.eclipse.ui.IWorkbenchPart;
import  org.eclipse.ui.PartInitException;
import  org.eclipse.ui.part.IPage;
import  org.eclipse.ui.part.IPageBookViewPage;
import  org.eclipse.ui.part.MessagePage;
import  org.eclipse.ui.part.PageBook;
import  org.eclipse.ui.part.PageBookView;


public   class  ExampleView  extends  PageBookView  implements  ISelectionListener{

    
public  ExampleView() {
    }

    @Override
    
protected  IPage createDefaultPage(PageBook book) {
        MessagePage page 
=   new  MessagePage();
        initPage(page);
        page.createControl(book);
        page.setMessage(
" An example view is not available. " );
        
return  page;
    }

    @Override
    
public   void  init(IViewSite site)  throws  PartInitException {
        
super .init(site);
        site.getPage().addSelectionListener(
this );
    }

    @Override
    
public   void  dispose() {
        getSite().getPage().removeSelectionListener(
this );
        
super .dispose();
    }

    @Override
    
protected  PageRec doCreatePage(IWorkbenchPart part) {
        
//  Try to get a custom page
        Object obj  =  part.getAdapter(IExamplePage. class );
        
if  (obj  instanceof  IExamplePage) {
            IExamplePage page 
=  (IExamplePage)obj;
            
if  (page  instanceof  IPageBookViewPage) 
                initPage((IPageBookViewPage)page);
            page.createControl(getPageBook());
            
return   new  PageRec(part, page);
        }
        
//  Use the default page
         return   null ;
    }

    @Override
    
protected   void  doDestroyPage(IWorkbenchPart part, PageRec pageRecord) {
        IExamplePage page 
=  (IExamplePage) pageRecord.page;
        page.dispose();
        pageRecord.dispose();
    }

    @Override
    
protected  IWorkbenchPart getBootstrapPart() {
        IWorkbenchPage page 
=  getSite().getPage();
        
if  (page  !=   null )
            
return  page.getActiveEditor();
        
else
            
return   null ;
    }

    @Override
    
protected   boolean  isImportant(IWorkbenchPart part) {
        
return  (part  instanceof  IEditorPart);
    }

    @Override
    
public   void  createPartControl(Composite parent) {
        
super .createPartControl(parent);
    }

    
public   void  selectionChanged(IWorkbenchPart part, ISelection selection) {
        
//  we ignore our own selection or null selection
         if  (part  ==   this   ||  selection  ==   null ) {
            
return ;
        }

        
//  pass the selection to the page
         if  ( ! (getCurrentPage()  instanceof  IExamplePage))
            
return ;
        IExamplePage page 
=  (IExamplePage) getCurrentPage();
        
if  (page  !=   null ) {
            page.selectionChanged(part, selection);
        }
    }
    
}

在上面这个View里,createDefaultPage()方法创建的Page是当活动WorkbenchPart不是我们所关心类型时所显示 的信息,由MessagePage实现;isImportant()规定了这个View对什么样的WorkbenchPart感兴趣,在上面的例子里是只 处理IEditorPart,作为对照,Eclipse的PropertySheet对所有类型的WorkbenchPart都有兴趣,除了它自己;如果 活动WorkbenchPart是"Important"的,并且通过它的getAdapter()方法能得到我们需要的Page,则这个Page会显示 在这个View里,否则还将显示缺省的MessagePage。

现在来看一下怎样实现自己的Page。一般要先定义一个继承自IPage的接口,它的一个作用是给 WorkbenchPart#getAdapter()方法作为参数以标识我们需要的Page类型,如果前面PageBookView子类已经实现了 ISelectionListener则它多半也要实现此接口,如下所示:

 

import  org.eclipse.ui.ISelectionListener;
import  org.eclipse.ui.part.IPage;

public   interface  IExamplePage  extends  IPage, ISelectionListener{

}

然后是具体的Page类,这个类其实和以前我们实现ViewPart的代码很相似,它继承自org.eclipse.ui.part.Page并实 现刚才定义的接口,最重要的当然就是createControl()方法,如果需要还有selectionChanged()方法:

 

import  org.eclipse.swt.SWT;
import  org.eclipse.swt.widgets.Composite;
import  org.eclipse.swt.widgets.Control;
import  org.eclipse.ui.part.Page;

/**
 * 
@author  zhanghao
 *
 
*/
public   class  ExamplePage  extends  Page  implements  IExamplePage {

    Text txtName;

    
public  ExamplePage() {
        
super ();
    }

    @Override
    
public   void  createControl(Composite parent) {
        
// Create your autual view UI here
        txtName  =   new  Text(parent, SWT.BORDER);
    }

    @Override
    
public  Control getControl() {
        
return  txtName;
    }

    @Override
    
public   void  setFocus() {

    }

    
public   void  selectionChanged(IWorkbenchPart part, ISelection selection) {
        String name 
=   // Get information from selection
        txtName.setText(name);
    }
}

补充一点,每个Page具有独立的ActionBar,也就是说要为PageBookView添加菜单或工具条项应该在Page里完成,一般实现在 init()方法里。

现在还差一个步骤没做,那就是要在WorkbenchPart的getAdapter()方法里对这个View做出反应(这要求 WorkbenchPart可访问自定义的Page类),典型情况下我们用自己的Page接口作为参数,代码类似下面这样:

 

public  Object getAdapter(Class type) {
    
if  (type  ==  IExamplePage. class ) {
        
return   new  ExamplePage();
    }
    
return   super .getAdapter(type);
}

当然,和以前一样还是要在plugin.xml里注册这个View,以便使用者能够在Eclipse里通过"Window->Show View"菜单命令把它显示出来。

最后,和PropertySheet相比,这样的实现还有一个小缺陷,那就是第一次打开这个View的时候不能显示Editor里当前选择的信息, 大家不妨试着解决这个问题。(提示:参考PropertySheet的partActivated()方法)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值