The Eclipse Tabbed Properties View

来源:百度文库 编辑:神马文学网 时间:2024/07/03 12:32:19
Copyright© 2006 International Business Machines Corp.
Eclipse Corner Article

The Eclipse Tabbed Properties View
Summary
The Eclipse workbench provides a properties view which is used to view (and/or edit) properties of aselected item. In this article, you will learn how to use the tabbed properties view to create anenhanced user interface for the properties view.
By Anthony Hunter, IBM
February 19, 2006
Introduction
The Eclipse workbench provides a properties view, which is described in detail in the articleTake control of your properties.The default user interface is table with property and value pairs, andthe value being modified using a standard dialog cell editor.
The workbench provides extensions to define a custom user interfacefor the properties view. By making use of thise extensions, the tabbedproperties view has been created.
The tabbed properties view allows you to create any user interfacefor your properties. In addition, you can create user interfaces forelements that do not implement an IPropertySource. Indeed theproperties view can be extended to view any data for the selection inyour workbench part.
As an example, here was the properties view for the example in theTake control of your properties.

The tabbed properties view can be used to create a different user interface.

History
The tabbed properties view was authored by IBM and was usedinternally in the IBM Rational Software Architect, IBM WebSphereIntegration Developer, and other IBM products based on the Eclipseplatform.
The tabbed properties view was contributed to Eclipse open source and became part of theEclipse Web Tools Platform project.
With Eclipse 3.2 M5, the tabbed properties view has moved to the Eclipse core platform.
The Tabbed Properties View is implemented using the org.eclipse.ui.views.properties.tabbed plug-in.
Examples
Here are some other examples of the tabbed properties view in action.
This example comes from the XML Schema Editor available inEclipse WTP version 0.7

This example comes from the Logic Shapes example available inEclipse GMF version 1.0 M4.

This example comes from the UML Modeler available inIBM Rational Software Architect version 6.0

Reprinted with the permission of IBM Corporation. © International Business Machines Corp. 2005
This example comes from the BPEL Editor available inIBM WebSphere Integration Developer version 6.0

Reprinted with the permission of IBM Corporation. © International Business Machines Corp. 2005
This example comes from the HTML Editor available inIBM Rational Web Software Developer for WebSphere Software version 6.0

Reprinted with the permission of IBM Corporation. © International Business Machines Corp. 2005
The Tabbed Properties View Extension Points
The tabbed properties view is configured by implementing threeextension. Each tabbed properties view is composed of a propertycontributor who contributes one or more property tabs. Each propertytab is filled with one or more sections. The highlighted example belowillustrates how they are organized. For the current selection, theproperty contributor has enabled two tabs in the tabbed propertiesview, Button and Advanced. The Button tab is highlighted and is theactive tab. The Button tab has enabled three active sectionshighlighted on the right.

A section is simply a widget or a composite containing a group ofwidgets that maps to one property, multiple properties or some conceptindependent of the properties of a selection.
Property Contributor
The org.eclipse.ui.views.properties.tabbed.PropertyContributorextension point is the key for your tabbed properties view. It mostimportantly identifies the unique contributor identifier for your tabsand sections. Most frequently, this identifier matches the uniqueworkbench part id that is contributing the tabbed properties view.
Note that a property contributor can be shared among severalworkbench parts. For example, an application may have an explorer view,editor and outline whose selections share a common set of properties.In this case, all three workbench parts can share the same tabbedproperties view as identified by the unique contributor identifier.
A workbench part cannot make use of two or more propertycontributors. It can identify a single property contributor byimplementing the ITabbedPropertySheetPageContributor interface.
The PropertyContributor extension point also defines the following attributes:
typeMapper The class that implements the type mapper.
labelProvider The class that implements the label provider for the title bar.
propertyCategory One or more category attributes used to group the tabs.
Property Tabs
The org.eclipse.ui.views.properties.tabbed.PropertyTabsextension point describes the tabs for a contributor. Each tab belongsto one contributor as identified by its unique contributor identifier.The PropertyTabs extension point can define one or more tabs through the PropertyTab attribute.
A ProperyTab defines the following attributes:
id The unique id for the tab.
label The label to be displayed on the tab.
category The category from the PropertyContributor extension point used to group tabs.
afterTab When there is more than one tab in a category, tabs are sorted by the afterTab attribute.
image The optional image to display on the tab.
indented true if the tab is indented.
Property Sections
The org.eclipse.ui.views.properties.tabbed.PropertySectionsextension point describes the sections for a contributor. Each sectionbelongs to one configuration as identified by its unique contributoridentifier.
The PropertySections extension point can define one or more sections through the PropertySection attribute. Each section belongs to one tab as identified by its unique tab identifier.
The PropertySection defines the following attributes:
id The unique id for the section.
tab The unique tab id in which this section appears.
class The class that implements the section
afterSection When there is more than one section in a tab, sections are sorted by the afterSection attribute.
filter The class that implements a section filter.
enablesFor a value indicating the selection count which must be met to enable the section. If specified and the condition is not met, the section is filtered. If omitted, the section enablement is not affected.
The following attribute formats are currently supported:
n - a precise number of items selected. For example: enablesFor=" 1" enables the section only when 1 item is selected
The PropertySection also defines one or more input type attributes. Each type is a class or interface that the selection must match for the section to be displayed on the tab.
Implementing the Tabbed Properties View
Let us now take the example fromTake control of your propertiesand make it use the tabbed property view, as we first showed at thestart of this article. The source code for this example can be foundtheCVS repository.
Before proceeding, we add the dependency to the org.eclipse.ui.views.properties.tabbed plug-in in the required plug-ins list.
Updating the Sample View
A workbench part that provides a tabbed property view needs to implement the ITabbedPropertySheetPageContributor interface. This interface has the single method getContributor()that must be implemented, which returns the contributor identifier foryour configuration. We will simply use the view identifier andimplement the method as below:
public String getContributorId() {return getSite().getId();}
We also need to tell the workbench to use the tabbed property view.Each workbench part can define its own custom property sheet page byproviding an adaptable for IPropertySheetPage. The workbench will call your view‘s getAdapter() method and ask for an IPropertySheetPage. It is at this point that we tell Eclipse to use our tabbed property sheet page.
public Object getAdapter(Class adapter) {if (adapter == IPropertySheetPage.class)return new TabbedPropertySheetPage(this);return super.getAdapter(adapter);}Add a PropertyContributor extension
Next we add the PropertyContributor extension to our plug-in:

We need to define the contributor identifier, which is the view identifier in our case.
At this point we can now run our plug-in and when you look at the properties view, you will see "Properties are not available".
The tabbed property sheet page has successfully been implemented.The page took the unique identifier and looked up the tabs and sectionsthat match the current selection ("button") and did not find any todisplay. So you see the message "Properties are not available".

The next stage is to define tabs and sections.
Add a PropertyTabs extension
The first thing we need to do before adding tabs is to define a property category in our PropertyContributor extension.

We have added one category called sample.
Next we can add the PropertyTabs extension to our plug-in.
category="sample"id="mview.ButtonTab"label="Button"/>afterTab="mview.ButtonTab"category="sample"id="mview.AdvancedTab"label="Advanced"/>
We have defined two tabs in our example by providing two propertyTab attributes.
We must provide the tab id, category and label for each tab.
Our tabs are named button () and advanced ().
We also define the Advanced tab will be displayed after the Button tab.
Both our tabs are in our sample category.
Add a PropertySections extension
Finally we can add the PropertySections extension point to our plug-in.

All our sections apply to the input type ButtonElement.
The button tab is given three sections, the advanced tab one section.
Each section has the tab identifier, unique identifier for the section and the class that implements the section.
Property Section
Here is the code for our label section.
/******************************************************************************** Copyright (c) 2006 IBM Corporation and others.* All rights reserved. This program and the accompanying materials* are made available under the terms of the Eclipse Public License v1.0* which accompanies this distribution, and is available at* http://www.eclipse.org/legal/epl-v10.html** Contributors:* IBM Corporation - initial API and implementation*******************************************************************************/package mview.views;import org.eclipse.jface.util.Assert;import org.eclipse.jface.viewers.ISelection;import org.eclipse.jface.viewers.IStructuredSelection;import org.eclipse.swt.SWT;import org.eclipse.swt.custom.CLabel;import org.eclipse.swt.events.ModifyEvent;import org.eclipse.swt.events.ModifyListener;import org.eclipse.swt.layout.FormAttachment;import org.eclipse.swt.layout.FormData;import org.eclipse.swt.widgets.Composite;import org.eclipse.swt.widgets.Text;import org.eclipse.ui.IWorkbenchPart;import org.eclipse.ui.views.properties.IPropertySource;import org.eclipse.ui.views.properties.tabbed.AbstractPropertySection;import org.eclipse.ui.views.properties.tabbed.ITabbedPropertyConstants;import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;/*** The Label section on the Button tab.** @author Anthony Hunter*/public class LabelSectionextends AbstractPropertySection {private Text labelText;private ButtonElement buttonElement;private ModifyListener listener = new ModifyListener() {public void modifyText(ModifyEvent arg0) {ButtonElementProperties properties = (ButtonElementProperties) buttonElement.getAdapter(IPropertySource.class);properties.setPropertyValue(ButtonElementProperties.PROPERTY_TEXT,labelText.getText());}};public void createControls(Composite parent,TabbedPropertySheetPage aTabbedPropertySheetPage) {super.createControls(parent, aTabbedPropertySheetPage);Composite composite = getWidgetFactory().createFlatFormComposite(parent);FormData data;labelText = getWidgetFactory().createText(composite, ""); //$NON-NLS-1$data = new FormData();data.left = new FormAttachment(0, STANDARD_LABEL_WIDTH);data.right = new FormAttachment(100, 0);data.top = new FormAttachment(0, ITabbedPropertyConstants.VSPACE);labelText.setLayoutData(data);labelText.addModifyListener(listener);CLabel labelLabel = getWidgetFactory().createCLabel(composite, "Label:"); //$NON-NLS-1$data = new FormData();data.left = new FormAttachment(0, 0);data.right = new FormAttachment(labelText,-ITabbedPropertyConstants.HSPACE);data.top = new FormAttachment(labelText, 0, SWT.CENTER);labelLabel.setLayoutData(data);}public void setInput(IWorkbenchPart part, ISelection selection) {super.setInput(part, selection);Assert.isTrue(selection instanceof IStructuredSelection);Object input = ((IStructuredSelection) selection).getFirstElement();Assert.isTrue(input instanceof ButtonElement);this.buttonElement = (ButtonElement) input;}public void refresh() {labelText.removeModifyListener(listener);ButtonElementProperties properties = (ButtonElementProperties) buttonElement.getAdapter(IPropertySource.class);labelText.setText(properties.strText);labelText.addModifyListener(listener);}}
A section in a tab is represented by the ISection interface. Clients should extend AbstractPropertySection rather than implementing ISection directly.
When implementing a section, there are three methods a section must implement:
ISection.createControls() creates the controls for the section.
ISection.setInput() is where the section is given the selection from the contributing workbench part.
ISection.refresh() is where the section refreshes the contents of the controls based on the input.
Section Layout
Standard Eclipse SWT widgets are used in ISection.createControls(). Any widget that can be hosted in an SWT Composite can be displayed in a section.
Clients should take advantage of the widget factory provided by theframework to achieve a common look between property sections. Thewidget factory is available from AbstractPropertySection.getWidgetFactory() ().
AbstractPropertySection defines several additional items for an ISection that implementers need to be aware of.
In our example, we had three sections, button, size and font. Sincesections are not aware of each other, it is difficult to know how toline up the labels for sections on the left hand side of the composite.For this reason, we make use of AbstractPropertySection.STANDARD_LABEL_WIDTH ().
We make use of ITabbedPropertyConstants () to align the controls in the sections.
ISection.getMinimumHeight() returns the minimum height needed by this section. AbstractPropertySection returns a default value of SWT.DEFAULT to indicate that no minimum height is defined.
ISection.shouldUseExtraSpace() determines whether asection would like extra height space in casethere is some left. Normally this is only true when the section is thelast to be displayed on a tab or is the only section on a tab. AbstractPropertySection returns false by default.
Lifecycle of a Section
The lifecycle of a section is as follows:
ISection.createControls()
ISection.setInput()
ISection.aboutToBeShown()
ISection.refresh()
ISection.aboutToBeHidden()
ISection.dispose()
Implementers of this class should be aware that a section instancemight be reused for different input objects (as long as they are validsection inputs). It means that ISection.setInput can be called at any time between ISection.createControls andISection.dispose.
When an input change event occurs, such as a tab selection or a workbench selection change, a section is sent:
ISection.setInput()
ISection.refresh()
When a part activation event occurs, such as the workbench part activation event, a section is sent:
ISection.setInput()
ISection.aboutToBeShown()
ISection.refresh()
ISection.setInput()
ISection.refresh()
This is because both a tab selection event and an input selection event have occurred.
Model Listeners
When a property sheet page is visible, the model could be changedoutside of the property view. In this case we want to add a listener sothat we can update the visible controls based on new model values. Thisis done using ISection.aboutToBeShown().
ISection.aboutToBeShown() notifies the section that itscontrols are about to be shown. It is expected that sections enabledomain related functions such as adding listeners.
ISection.aboutToBeHidden() notifies the section thatits controls are about to be hidden and should disable domain relatedfunctions such as removing listeners.
Since the controls are not yet visible in ISection.aboutToBeShown(), the section should wait for ISection.refresh() to be called to updating the section controls.
The listener when receiving a change event should make use of ISection.refresh() to update the controls for the section.
Advanced Section
When we have complex applications with multiple IPropertySource, we may not want to provide custom tabs and sections for all the properties available for a selection. Clients can reuse the AdvancedPropertySection class to display the "original" table format properties view.
As an example, here is the advanced tab for our exampling showing the "original" properties view from theTake control of your properties.

Additional Options
Type Mapper
The PropertyContributor extension point defines an optional typeMapper attribute. This attribute defines a type mapper class that implements ITypeMapper or preferably extends the AbstractTypeMapper class.
When a set of objects are selected in the workbench part, the tabbed properties view matches the type of these objects with the input type attributes defined in the PropertySectionsextensions. In some cases, the selection will be user interfaceobjects, such as tree nodes. A type mapper is used to map between theseuser interface objects and a domain model object.
An example for a type mapper for org.eclipse.jface.viewers.TreeNode where we are interested in the value of the tree node:
public class TypeMapperextends AbstractTypeMapper {public Class mapType(Object object) {if (object instanceof TreeNode) {return ((TreeNode) object).getValue().getClass();}return super.mapType(object);}}
A second example of a type mapper can be found in the tabbed properties logic example based onEclipse GEF. Elements on a diagram are all EditPart. We are interested in the type of the underlying model:
public class LogicElementTypeMapperextends AbstractTypeMapper {public Class mapType(Object object) {if (object instanceof EditPart) {return ((EditPart) object).getModel().getClass();}return super.mapType(object);}}Section Filtering
The PropertySection extension point defines an optional filter attribute. This attribute defines a filter for a section. A filter is a class that implements the org.eclipse.jface.viewers.IFilter interface. It is used to filter a section from display for a selection even though it meets the input type criteria.
Note that a filter is used to override the type mapper and input forthe selection. When a filter is specified, the type mapper and inputare ignored for that section. In the case where filter is specified, input type need not be provided.
Title Bar
The PropertyContributor extension point defines an optional labelProviderattribute. This attribute defines a label provider for a title bar forthe tabbed properties view. The title bar is used as a usabilityenhancement to display information about the current selection in thecontributing workbench part. You can display the icon and name of theselected object. Frequently, groups put the type of the selectedobjects in brackets and indicate the number of objects selected.
Tab Ordering
Tabs are ordered by the categories defined by the PropertyContributor extension. When there is more than one tab in a category, tabs are sorted using the afterTab attribute in the PropertyTab extension.
Section Ordering
When there is more than one section on a tab, sections are sorted using the afterSection attribute in the PropertySection extension.
Section Selection Count Enablement
The PropertySection extension point defines an optional enablesForattribute. This attribute will cause the section to be enabled for aspecific selection count. Most frequently this attribute is set to "1"to filter a section when multiple objects are selected.
Alternate Property Configuration for a Selection
Clients can extend the property configuration for a workbench partby implementing tab and section extensions in their plug-in. There aretimes when it is desirable for clients provide a top level propertycontributor configuration as well. For example, a project explorer mayhave multiple clients contributing elements to a tree. The core projectexplorer will define a properties configuration with a uniquecontributor identifier. Clients can add tabs and sections by using thesame contributor identifier in their plug-in. If a client already hastabs and sections with a different contributor identifier that matchestheir editor, it would not be desirable to have to copy all theextensions to display when its custom tree nodes are selected
It is possible to have the elements in a selection implement or adapt to the ITabbedPropertySheetPageContributor interface. If all the elements in a selection return the same identifier to getContributorId() for a selection, then that alternate property configuration will be displayed in the properties view for that selection.
Additional Examples
There are additional examples available that demonstrate the use of the tabbed properties view:
Tabbed Properties Tests View- a JUnit tests plug-in with a sample view that demonstrates examplesof every option available through the tabbed properties view extensionpoints.
Tabbed Properties Logic Example - tabbed properties view based on theEclipse GEF Logic Example
Tabbed Properties Hockey League Example - tabbed properties view with anEclipse EMF Hockey League model
Conclusion
In this article, you have seen how to use the tabbed properties view to create anenhanced user interface for the properties view.