Introduction
This document describes how the work item component can be extended to display an attribute with a custom presentation. Our example implements an alternative presentation for a boolean attribute. Instead of a check box, our custom presentations will show a starred image. When true, the star is filled in and when false the star is outlined.
For more information about configuring presentations and defining custom attributes, please see Work Item Editor Presentations.
There is an additional example on how to develop a custom attribute presentation that handles calculated attributes and attribute dependencies in CalculatedAttributePresentation.
Contributing to the Work Item Editor
Contributing a new presentation to the work item editors consists of two steps for each editor:
- Implement the presentation
- Bind the abstract presentation ID to the concrete implementation class
The kind
for a presentation can be determined in two ways: either a kind is
declared in the Process Configuration directly (blue), or a kind can be
retrieved from the Attribute type registry (orange) where
the type of an attribute is bound to a default presentation. The Eclipse
UI instantiates the bound java class and displays it in the editor.
We assume that our new presentation has an ID of com.example.star.
This presentation ID can be chosen arbitrarily but should be prefixed
with the
implementing component's namespace. Any boolean attribute can then be
associated with our new presentation ID and will be shown using the
respective control
both in the web and in the rich client. Let's start with the Eclipse UI
implementation:
Editor Presentations
Editor presentations for the work item editor in the eclipse ui are registered to thecom.ibm.team.workitem.ide.ui.editorPresentations
extension point. An extension has to specify whether it is intended to
work on an attribute or not and has then to subclass either PresentationPart or AttributePart.
The com.ibm.team.workitem.common.attributeTypePresentationIdBinding
extension point allows to bind a presentation id to an attribute type.
Presentations configured with an attribute but without a kind will use
the presentation specified in this extension point. As our example is an
additional presentation, we will not register it to be default for
boolean.
The presentation shows the attribute name on the left side and a toggle button with the star icon on the right side. Let's have a look at some parts of the code:
Presentation Updater:
private IPresentationUpdater fPresentationUpdater= new AbstractPresentationUpdater() {
@Override
public void setVisible(boolean visible) {
List<Control> changedControls= new ArrayList<Control>();
if (fAttributeName != null && !fAttributeName.isDisposed()) {
TeamFormUtil.setVisible(fAttributeName.getLayoutControl(), visible);
changedControls.add(fAttributeName.getLayoutControl());
}
if (fStar != null && !fStar.isDisposed()) {
TeamFormUtil.setVisible(fStar, visible);
changedControls.add(fStar);
}
Util.updateFormLayout(changedControls.toArray(new Control[changedControls.size()]));
};
@Override
public void setRequired(boolean required) {
if (fAttributeName != null && !fAttributeName.isDisposed()) {
fAttributeName.setRequired(required);
}
}
@Override
public void attributeChanged(WorkItemChangeEvent event) {
handleValueChanged();
};
};
This is the presentation updater that handles events from the
presentation handler infrastructure. Such changes include visibility,
attribute changes, required property annotation, dependency changes (not
implemented in this example) and status reporting (not implemented in
this example). The updater is registered and de-registered when the
input of the work item editor changes or the editor is closed.
Button:
@OverrideThis createContent method uses the TeamFormLayout infrastructure to align the label and the button on the respective guides. The work item editor has two guides in a section. For small sections
public void createContent(ITeamFormLayout formLayout) {
final WorkItemEditorToolkit toolkit= (WorkItemEditorToolkit) getSite().getToolkit();
Composite parent= formLayout.getContainer();
if (isLabelVisible()) {
fAttributeName= new RequiredPropertyLabel(parent, toolkit, getBackgroundStyle());
formLayout.add(fAttributeName.getLayoutControl(), ITeamFormConfiguration.LABEL_GUIDE);
}
fResourceManager= new LocalResourceManager(JFaceResources.getResources(), parent);
fStar= toolkit.createButton(parent, "", SWT.TOGGLE | SWT.FLAT, getBackgroundStyle()); //$NON-NLS-1$
TeamFormLayouts.setLayoutData(fStar, ITeamFormData.BUTTON);
formLayout.add(fStar, ITeamFormConfiguration.CONTENT_GUIDE);
if (isReadOnly()) {
fStar.setEnabled(false);
} else {
fStar.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent e) {
}
public void widgetSelected(SelectionEvent e) {
if (fWorkingCopy != null) {
// Change the value on the work item
fWorkingCopy.getWorkItem().setValue(getAttribute(), fStar.getSelection());
}
}
});
}
}
LABEL_GUIDE and CONTENT_GUIDE, for wide sections LABEL_GUIDE and WIDE_CONTENT_GUIDE. The example also shows how to correctly respect the labelVisible and readOnly properties. When the button is clicked, the value is written to the work item.
Get Value
// Get the value from the resolved work itemThis method is used to get the value in a safe way from the work item. It demonstrates the use of the resolved work item which allows to get a resolved value directly (this is not a problem for boolean, but for example for an
private boolean getNonNullValue() {
Boolean value= null;
if (fWorkingCopy != null && getAttribute() != null && fWorkingCopy.getWorkItem().hasAttribute(getAttribute())) {
WorkItemUIWorkingCopy uiCopy= (WorkItemUIWorkingCopy) fWorkingCopy.getAdapter(IWorkItemUIWorkingCopy.class);
ResolvedWorkItem workItem= uiCopy.getResolvedWorkItem();
value= (Boolean)workItem.getValue(getAttribute());
}
if (value == null) {
value= Boolean.FALSE;
}
return value.booleanValue();
}
IContributor where the work item would return an IContributorHandle instead).
Update UI
// The value has changed, update the UIUpdate the UI when the value has changed. This is the case when the user clicks the button, or a different (or the initial) input is set to the editor.
private void handleValueChanged() {
if (!fStar.isDisposed()) {
boolean value= getNonNullValue();
if (fStar.getSelection() != value) {
fStar.setSelection(value);
}
if (value) {
fStar.setImage(JazzResources.getImageWithDefault(fResourceManager, ImagePool.STAR_ICON_ENABLED));
} else {
fStar.setImage(JazzResources.getImageWithDefault(fResourceManager, ImagePool.STAR_ICON_DISABLED));
}
}
}
Set Input
@OverrideWhen the editor gets the input, remove the old presentation updater (if necessary), add the new updater, set the attribute name and update the star button.
public void setInput(Object input) {
removeListeners();
if (input instanceof WorkItemEditorInput && ((WorkItemEditorInput) input).isResolved() && getAttribute() != null) {
WorkItemEditorInput workItemEditorInput= (WorkItemEditorInput) input;
fWorkingCopy= workItemEditorInput.getWorkingCopy();
addListeners();
if (fAttributeName != null && fStar != null && !fAttributeName.isDisposed()) {
fAttributeName.setText(NLS.bind(ATTRNAME_COLON, getAttribute().getDisplayName()));
}
if (fStar != null && !fStar.isDisposed()) {
handleValueChanged();
}
} else if (input instanceof WorkItemEditorInputFuture) {
fWorkingCopy= null;
}
}
Add Presentation Updater
private void addListeners() {
PresentationHandlerManager mgr= (PresentationHandlerManager) getSite().getAdapter(PresentationHandlerManager.class);
if (mgr != null) {
mgr.addPresentationUpdater(fPresentationUpdater, getDescriptor());
}
}
The presentation updater is registered to the handler infrastructure. Removing the updater is very similar.
Presentation Binding
The presentation created above is bound to a Kind ID in theplugin.xml. I needs an attribute and can handle attributes of type boolean.
<extension point="com.ibm.team.workitem.ide.ui.editorPresentations">
<editorPresentation
id="com.example.star"
displayName="Star"
class="com.example.presentations.StarAttributePart"
needsAttribute="true" >
<attributeType id="boolean" />
</editorPresentation>
</extension>
Resources
- StarAttributePart.java: Star attribute implementation for the eclipse ui work item editor (Java source)
Conclusion
With the implementations and bindings in place, we are now ready to define a new custom attribute and to configure the work item editors to use the new presentation for it: We define a boolean attribute named 'Has Star' and add it to the Details section using the 'Star' presentation:
The attribute is then editable using our new control:
Attachement
StarAttributePart.java : Star implementation for the eclipse ui work item editor
풍차
- 2010.11.24
- 17:23:49
- (*.109.178.9)
boolean 이외의 attributeType에 지정할 땐, process source를 보고, attribute type id를 설정해주면 된다고 합니다.




위 함수들간의 관계는 아래 처럼 해석해 봅니다.