[心缘地方]同学录
首页 | 功能说明 | 站长通知 | 最近更新 | 编码查看转换 | 代码下载 | 常见问题及讨论 | 《深入解析ASP核心技术》 | 王小鸭自动发工资条VBA版
登录系统:用户名: 密码: 如果要讨论问题,请先注册。

[整理]RCP插件开发,如何使用properties视图,[另一篇]

上一篇:[整理]RCP插件开发,如何使用properties视图。
下一篇:[整理]RCP插件开发,Propertes 视图中的属性项目的顺序问题

添加日期:2011/3/31 15:04:03 快速返回   返回列表 阅读5477次

========================================
Use IAdapter

By using the IAdaptable interface in your applications, you can provide different views of your objects without cluttering them with non-domain/UI specific code. In this example, I will provide a list of Contact objects to a ListViewer and that when selected, the ListViewer will broadcast the selection. The gold is the adapter which will convert the selected Contact to an IPropertySource which will be displayed in a PropertySheetViewer.

To get started, create a new plug-in that will contribute to the UI. You don’t need anything more than that.
The Contact class will consist of two attributes which are tied to the domain and a map for non-domain attributes. An example of a non-domain attribute would be the creation date or the last time the object was synchronised to a device.

首先,这是一个提供数据的Bean。


public class Contact {

    private String address;

    private String name;

    private Map properties;

    public Contact(String name, String address) {
        this.name = name;
        this.address = address;
    }

    public String getAddress() {
        return this.address;
    }

    public String getName() {
        return this.name;
    }

    public synchronized Map getProperties() {
        if (this.properties == null) {
            return Collections.emptyMap();
        }

        return new HashMap(this.properties);
    }

    public synchronized void setProperty(String key, Serializable value) {
        if (this.properties == null) {
            this.properties = new HashMap();
        }

        this.properties.put(key, value);
    }
}



I also created a simple manager which returns a list of populated Contact objects and some sample property attributes.

这个就是做了一些数据。


public class Manager {

    List contacts;

    public Manager() {
        this.contacts = new ArrayList();

        Contact contact = new Contact("Seamus Venasse", "141 Pueblo Crescent");
        contact.setProperty("Created", "2008/04/05 11:44");
        contact.setProperty("Submitted", "2008/04/05 11:53");
        this.contacts.add(contact);

        contact = new Contact("Derrick Law", "11 Boswell Crescent");
        contact.setProperty("Created", "2008/04/05 15:21");
        contact.setProperty("Submitted", "2008/04/07 09:48");
        this.contacts.add(contact);

        contact = new Contact("Noah Gehmair", "Boonies");
        contact.setProperty("Created", "2008/04/06 10:34");
        this.contacts.add(contact);
    }

    public Contact[] contacts() {
        return this.contacts.toArray(new Contact[0]);
    }

}



For the view, a ListViewer is used to display the contacts from the Manager and to also broadcast the selected Contact to the rest of the application.

这个是程序主体,用ListViewer来显示数据。
重要的还是这句话:getViewSite().setSelectionProvider(contactsList);
必须有。


public class ContactView extends ViewPart {

    public static final String ID = "us.pompo.adaptable.Contacts"; //$NON-NLS-1$

    @Override
    public void createPartControl(Composite parent) {
        Composite container = new Composite(parent, SWT.NONE);
        container.setLayout(new FillLayout());

        final ListViewer contactsList = new ListViewer(container, SWT.BORDER);
        contactsList.setLabelProvider(new ListLabelProvider());
        contactsList.setContentProvider(new ContentProvider());
        contactsList.setInput(Activator.getDefault().getContactManager());
        getViewSite().setSelectionProvider(contactsList);
    }

    @Override
        public void setFocus() {
    }

    class ContentProvider implements IStructuredContentProvider {

        public void dispose() {
        }

        public Object[] getElements(Object inputElement) {
            Manager contactManager = (Manager) inputElement;
            return contactManager.contacts();
        }

        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
        }
    }

    class ListLabelProvider extends LabelProvider {

        @Override
        public Image getImage(Object element) {
            return null;
        }

        @Override
        public String getText(Object element) {
            Contact contact = (Contact) element;
            return contact.getName();
        }
    }

}



The most important piece in the above code is setting the selection provider in the createPartControl method. Without this statement, the knowledge of the selection remains with the ListViewer and any listeners you’ve added.

There are also two inner classes to provide the data to the ListViewer and how the element object should be displayed.
Although not needed, I have created a perspective to ensure that both the ContactView and PropertySheetViewer are displayed.

下面,是做了一个布局,把Property视图给显示出来了。
它这里是用了内置的那个窗口,没有new一个。


public class ContactPerspective implements IPerspectiveFactory {

    public void createInitialLayout(IPageLayout layout) {
        String editorArea = layout.getEditorArea();
        layout.addView(ContactView.ID, IPageLayout.LEFT, 0.25f, editorArea);
        layout.addView(IPageLayout.ID_PROP_SHEET, IPageLayout.BOTTOM, 0.6f, editorArea);
    }

}



The only thing to note is that I am using the built-in Eclipse view for property sheets, IPageLayout.ID_PROP_SHEET, and not creating another view.

Now that the view is configured to broadcast the selected Contact object, any active class that implements ISelectionListener will receive the object in their selectionChanged method. The PropertySheetViewer is one such class that implements the ISelectionListener interface.

视图会广播被选中的对象,所有实现了ISelectionListener接口的对象的selectionChanged方法会被调用。

When a Contact is selected, the PropertySheetViewer.selectionChanged method will ask the platform if there are any known adapters that will convert a Contact object to an IPropertySource object. Since we haven’t created our adapter the PropertySheetViewer will not display anything.
PropertySheetViewer的selectionChanged方法会向平台询问,谁能转换选择的对象为IPropertySource对象。

So we need a IPropertySource which will display the properties from the Map in Contact. The ContactPropertySource will iterate through the keys of the map and return an array of IPropertyDescriptor objects. We only need a read-only view of the properties so we’ll use the PropertyDescriptor object.

这个就是原始数据类型,对应的支持Property视图的数据类型,实现IPropertySource接口就行。


public class ContactPropertySource implements IPropertySource {

    private Contact contact;

    public ContactPropertySource(Contact contact) {
        this.contact = contact;
    }

    @Override
    public Object getEditableValue() {
        return this;
    }

    @Override
    public IPropertyDescriptor[] getPropertyDescriptors() {
        List descriptors = new ArrayList();

        Map properties = this.contact.getProperties();
        for (String key : properties.keySet()) {
            PropertyDescriptor descriptor = new PropertyDescriptor(key, key);
            descriptor.setAlwaysIncompatible(true);
            descriptors.add(descriptor);
        }

        return descriptors.toArray(new IPropertyDescriptor[0]);
    }

    @Override
    public Object getPropertyValue(Object id) {
        Map properties = this.contact.getProperties();
        return properties.get(id);
    }

    @Override
    public boolean isPropertySet(Object id) {
        return false;
    }

    @Override
    public void resetPropertyValue(Object id) {
    }

    @Override
    public void setPropertyValue(Object id, Object value) {
    }
}



Like a Map, the identifier for a PropertyDescriptor must be unique as it will be passed to the getPropertyValue method to retrieve the value.

So how does PropertySheetViewer know about the ContactPropertySource? From registering an IAdapterFactory which will answer PropertySheetViewer’s earlier question of asking the platform if there are any known adapters that will convert a Contact object to an IPropertySource object.

再写一个适配器工厂,根据被选中的数据类型,返回对应的实现了IPropertySource接口的数据类型。


public class ContactAdapterFactory implements IAdapterFactory {

    private static final Class[] TYPES = { Contact.class };

    @Override
    public Object getAdapter(Object adaptableObject, Class adapterType) {
        if ((adaptableObject instanceof Contact) && (adapterType == IPropertySource.class)) {
            return new ContactPropertySource((Contact) adaptableObject);
        }
        return null;
    }

    @Override
    public Class[] getAdapterList() {
        return TYPES;
    }

}



This is a very simple object to understand. The two method from IAdapterFactory offer the ability to dynamically convert the Contact selection to an IPropertySource by returning a ContactPropertySource object.

First off the list is the getAdapertList method. This method tells the platform the types of objects it can adapt, otherwise this object would be asked for every type of selection.

The getAdapter method receives the object to adapt and the class type that is requested. In this example, when a Contact and IPropertySource are being passed, a new ContactPropertySource is returned. If the object cannot handle the request, a null is returned. The PropertySheetViewer ensures that the result is not null before using the adapted object.

还有一步,就是把工厂注册到平台上,否则平台哪里知道这有个工厂呢。
可以在Activator里注册,也可以在plugins.xml中写。
这个文章没写!
看这里吧:http://www.mytju.com/classcode/news_readNews.asp?newsID=314
The ContactAdapterFactory must now be registered to the platform either programmatically from the Activator or through the plugins.xml. I prefer to put as much configuration in the plugin.xml as possible.

Even though Contact does not implement the IAdaptable interface, it can still be represented in the adapter factory.
Now when a contact is selected, the PropertySheetViewer displays the entries from the properties map. The domain object does not know anything about IPropertySheet or IAdaptable
 

评论 COMMENTS
没有评论 No Comments.

添加评论 Add new comment.
昵称 Name:
评论内容 Comment:
验证码(不区分大小写)
Validation Code:
(not case sensitive)
看不清?点这里换一张!(Change it here!)
 
评论由管理员查看后才能显示。the comment will be showed after it is checked by admin.
CopyRight © 心缘地方 2005-2999. All Rights Reserved