This article will discuss customizing the model view.
The EMF Book covers editing ListViewers and TableViewers. A ListViewer displays items in its focused ViewerPane as a list, while a TableViewer can display the contents of a list of items in a grid-like view.
ListViewer CustomizationTo be added.
TableViewer CustomizationA TableViewer can be used to show the contents of model objects in a tabular view. The following is a description of how to set up a table viewer that will show model objects of the same feature within the model editor's viewer pane.
Set the TableProviders property to true in the Edit section the root object in the EMF .genmodel file.
Create a TableViewer member variable within the editor class
public class EMFProjectEditor
extends MultiPageEditorPart
implements
IEditingDomainProvider,
ISelectionProvider,
IMenuListener,
IViewerProvider,
IGotoMarker
{
...
/**
* This is the Bar table viewer
* @generated NOT
*/
protected TableViewer barViewer;
...
In createPages(), create a new self-contained block of code (using the {} delimiters). Then, make the following changes (be sure to change the method's java annotation to @generated NOT in order to keep EMF from overwriting any changes to the method). Much of this code can be copied from EMF default table viewer code in createPages().
/**
* @generated NOT
*/
public void createPages()
{
...
{
ViewerPane viewerPane =
new ViewerPane(getSite().getPage(), RealEditor.this) {
@Override
public Viewer createViewer(Composite composite) {
return new TableViewer(composite);
}
@Override
public void requestActivation() {
super.requestActivation();
setCurrentViewerPane(this);
}
};
viewerPane.createControl(getContainer());
/** This is the barViewer that we created **/
barViewer = (TableViewer)viewerPane.getViewer();
Table table = barViewer.getTable();
TableLayout layout = new TableLayout();
table.setLayout(layout);
table.setHeaderVisible(true);
table.setLinesVisible(true);
/** Here we add in the columns that will hold bar's properties **/
TableColumn column = new TableColumn(table, SWT.NONE); // This is the column for the label
layout.addColumnData(new ColumnWeightData(3, 100, true));
column.setText("Bar Label");
column.setResizable(true);
column = new TableColumn(table, SWT.NONE); // This is column for the first property
layout.addColumnData(new ColumnWeightData(2, 100, true));
column.setText("First Property");
column.setResizable(true);
column = new TableColumn(table, SWT.NONE); // This is the column for the second property
layout.addColumnData(new ColumnWeightData(2, 100, true));
descriptionColumn.setText("Second Property");
descriptionColumn.setResizable(true);
... /* and so on */
/* This will need to be changed for cell editing */
barViewer.setColumnProperties(new String [] {"a", "b", "c", "d"});
/*
* Here we need to subclass AdapterFactoryContentProvider.
* getElements() will need to only return instances of ``Bar'', assuming that ``Foo''
* is the root object containing instances of ``Bar'' in the model
* notifyChanged() will need to only pass on changes ``bar'' feature. Also,
* the viewer will be notified after every change (see ch 19, pg 586 in EMF book)
*/
barViewer.setContentProvider(
new AdapterFactoryContentProvider(adapterFactory)
{
public Object [] getElements(Object object)
{
return ((Foo)object).getInterfaces().toArray();
}
public void notifyChanged(Notification notification)
{
super.notifyChanged(new ViewerNotification(notification));
}
});
barViewer.setLabelProvider(new AdapterFactoryLabelProvider(adapterFactory));
/*
* This code ensures that the input to the table is always an instance of Foo
* so the call to getElements() is successful.
*/
Resource resource =
(Resource)editingDomain.getResourceSet().getResources().get(0);
Object rootObject = resource.getContents().get(0);
if (rootObject instanceof Foo) {
barViewer.setInput(rootObject);
}
/*****************************************************************************/
createContextMenuFor(barViewer);
int pageIndex = addPage(viewerPane.getControl());
/** Change the argument in getString to whatever is appropriate **/
setPageText(pageIndex, getString("_UI_Bar_feature"));
}
...
Finally, we need to make some changes to handleContentOutlineSelection() to prevent the table viewer's input from being changed by the current selection (EMF book, pg 586). Actual changes to the code are delimited by comment blocks.
public void handleOutlineContentSelection(ISelection selection)
{
...
if (currentViewerPane.getViewer() == selectionViewer ||
/* Add change here */
currentViewerPane.getViewer() == barViewer
/**/)
{
ArrayList selectionList = new ArrayList();
selectionList.add(selectedElement);
while (selectedElements.hasNext())
{
selectionList.add(selectedElements.next());
}
// Set the selection to the widget.
//
/*
* Here we will be replacing the following code:
* selectionViewer.setSelection(
* new StructuredSelection(selectionList));
*/
currentViewerPane.getViewer().setSelection(
new StructuredSelection(selectionList));
/**/
}
...
}
First, make sure that the item provider implements ITableItemLabelProvider like so:
/**
* This is the item provider adapter for a Bar object.
* <!-- begin-user-doc -->
* @implements ITableItemLabelProvider
* <!-- end-user-doc -->
* @generated
*/
public class BarItemProvider
extends ItemProviderAdapter
implements
IEditingDomainItemProvider
IStructuredItemContentProvider
ITreeItemContentProvider
IItemLabelProvider
IItemPropertySource
ITableItemLabelProvider
{
...
Now, implement getColumnText() and getColumnImage() as specified in ITableItemLabelProvider.
/**
* @generated NOT
*/
public String getColumnImage(Object object, int columnIndex)
{
switch(columnIndex) {
case 0: // First column: object label
return getText(object);
case 1: // Second column
...
case 2: // Third column
...
...
default:
return ""
}
}
/**
* @generated NOT
*/
public String getColumnImage(Object object, int columnIndex)
{
return getImage(object); // EMF book has different code, but this is simpler
}
Add support for ITableItemLabelProvider in the item provider adapter factory for model's item providers. Be sure to change the method annotation to @generated NOT
/**
* This creates an instance.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public EMFProjectItemProviderAdapterFactory()
{
supportedTypes.add(IStructuredItemContentProvider.class);
...
/* Add support for ITableItemLabelProvider here */
supportedTypes.add(ITableItemLabelProvider.class);
}