Table of Contents

  1. How to programmatically open a table
    1. In your own Composite container
  2. Table model
  3. Table configuration model
    1. Instantiation methods
  4. How to add your own cell editors
    1. unary features
    2. n-ary features
    3. model
    4. extension point
    5. example
  5. How to register custom Command factories

How to programmatically open a table

First, you must add these plug-ins to your plug-in dependencies:

Use:

ITableEditorFactory.DEFAULT.openOn(elements, editingDomain, description, tableConfiguration, context, parameter);

In your own Composite container

The NatTableWidget can be used in any Composite. If the widget is not provided with an IEditingDomainProvider, a default one will be used.

ITableWidgetFactory.INSTANCE.createTableWidget(parentComposite, editingDomainProvider, tableInstance, menuManager);

The ITableWidget returned by the factory proposes many API methods to manipulate the table. Among which:

Table model

A table is fully described by its model : see the metaclass Table in org.eclipse.emf.facet.widgets.table.metamodel. This means that when a table is saved, this model is serialized to an XMI file. This model contains all information needed to represent a table:

Table configuration model

A second model is used to define a table configuration. The main metaclass is TableConfiguration in org.eclipse.emf.facet.widgets.table.metamodel. TableConfiguration has the following references:

This table configuration can be passed to TableWidgetUtils#createTableInstance to create a table instance with this configuration.

Instantiation methods

An InstantiationMethod has:

To define an instantiation method, you must create a Facet that extends the metaclass that will be the context when creating new model elements.

For example, write the file /org.eclipse.emf.facet.widgets.table.examples.library.core/resources/instantiation.efacet contains:

<?xml version="1.0" encoding="ASCII"?>
<efacet:FacetSet xmi:version="2.0"
	xmlns:xmi="http://www.omg.org/XMI"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
	xmlns:efacet="http://www.eclipse.org/emf/facet/efacet/0.2.incubation/efacet"
	xmlns:javaQuery="http://www.eclipse.org/emf/facet/query/java/0.2.incubation/javaquery"
	name="org.eclipse.emf.facet.widgets.table.examples.library.core.instantiation"
	nsURI="http://www.eclispe.org/emf/facet/widgets/table/examples/library/core/instanciation"
	nsPrefix="instantiation">
  <eClassifiers xsi:type="efacet:Facet" name="org.eclipse.emf.facet.widgets.table.examples.library.core.instantiation">
    <extendedMetaclass href="http://www.eclipse.org/emf/2002/Ecore#//EObject"/>
    <facetOperations name="createWriter" ordered="false" unique="false" lowerBound="1">
      <eType xsi:type="ecore:EClass" href="http://www.eclipse.org/emf/facet/examples/library/0.2.incubation/library#//Writer"/>
      <eParameters name="tableParameter" ordered="false" unique="false" lowerBound="0">
        <eType xsi:type="ecore:EDataType" href="http://www.eclipse.org/emf/2002/Ecore#//EJavaObject"/>
      </eParameters>
      <eParameters name="editingDomain" ordered="false" unique="false" lowerBound="0">
        <eType xsi:type="ecore:EClass" href="http://www.eclipse.org/emf/2002/Ecore#//EJavaObject"/>
      </eParameters>
      <query xsi:type="javaQuery:JavaQuery" implementationClassName="org.eclipse.emf.facet.widgets.table.examples.library.core.internal.query.eobject.CreateWriter"/>
    </facetOperations>
  </eClassifiers>
</efacet:FacetSet>

The FacetOperation has to have two EJavaObject parameters : one for the table parameter, and the other one for the editing domain.

Then you need to write the Java query implementation that does the actual instantiation. The "source" is the Facet's extendedMetaclass, the return type is the FacetOperation's eType, and the "editingDomain" parameter you receive is the one you defined in your FacetOperation. The query should not modify the model directly, but it should instead do all modifications through the editing domain so that changes can be canceled:

package org.eclipse.emf.facet.widgets.table.examples.library.core.internal.query.eobject;

import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.facet.efacet.core.exception.DerivedTypedElementException;
import org.eclipse.emf.facet.efacet.examples.library.metamodel.library.LibraryFactory;
import org.eclipse.emf.facet.efacet.examples.library.metamodel.library.LibraryPackage;
import org.eclipse.emf.facet.efacet.examples.library.metamodel.library.Writer;
import org.eclipse.emf.facet.efacet.metamodel.v0_2_0.efacet.ParameterValue;
import org.eclipse.emf.facet.query.java.core.IParameterValueList2;
import org.eclipse.emf.facet.widgets.celleditors.ICommandFactoriesRegistry;
import org.eclipse.emf.facet.widgets.celleditors.ICommandFactory;

public class CreateWriter implements org.eclipse.emf.facet.query.java.core.IJavaQuery2<EObject, Writer> {

	public Writer evaluate(final EObject source,
			final IParameterValueList2 parameterValues,
			final org.eclipse.emf.facet.efacet.core.IFacetManager facetManager)
			throws DerivedTypedElementException {
		Writer result = null;
		final ParameterValue editingDomParam = parameterValues
				.getParameterValueByName("editingDomain"); //$NON-NLS-1$
		if (source == null) {
			throw new DerivedTypedElementException(
					"The source must not be null"); //$NON-NLS-1$
		}
		if (editingDomParam == null) {
			throw new DerivedTypedElementException(
					"An editing domain parameter must exists."); //$NON-NLS-1$
		}
		if (!(editingDomParam.getValue() instanceof EditingDomain)) {
			throw new DerivedTypedElementException(
					"An editing domain parameter must not be null."); //$NON-NLS-1$
		}
		final EditingDomain editingDomain = (EditingDomain) editingDomParam
				.getValue();
		final ICommandFactory cmdFactory = ICommandFactoriesRegistry.INSTANCE
				.getCommandFactoryFor(editingDomain);
		result = LibraryFactory.eINSTANCE.createWriter();
		final Command command = cmdFactory.createAddCommand(editingDomain,
				source, LibraryPackage.eINSTANCE.getLibrary_Writers(),
				result);
		editingDomain.getCommandStack().execute(command);
		return result;
	}
	
}

Then you have to write a table configuration. For example /org.eclipse.emf.facet.widgets.table.examples.library.core/resources/writers.tableconfiguration contains an instantiation method and references the instantiation operation defined in the above instantiation.efacet:

<tableconfiguration:TableConfiguration
	xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
	xmlns:tableconfiguration="http://www.eclipse.org/emf/facet/widgets/table/0.2.0.incubation/tableconfiguration">
  <instantiationMethod name="Create Writer" description="The action will instantiate a new writer and link it to the library.">
    <instantiationOperation href="instantiation.efacet#//InstantiationMethods/createWriter"/>
  </instantiationMethod>
</tableconfiguration:TableConfiguration>

How to add your own cell editors

unary features

Cell editors for unary features must be defined in classes that implement the IModelCellEditor interface. You must implement two methods:

When the user accepts the change, you must call the commit() method on IModelCellEditHandler so that the value is set on the feature.

If the user cancels the edition, you should simply call dispose() on your cell editor control.

n-ary features

Cell editors for n-ary features must be defined in classes that implement the INaryFeatureCellEditor interface.

You must implement the activateCell(…) method, to create the SWT Control for the cell editor under the given parent Composite.

For editing n-ary features, you don't call the commit() method. Instead, you should directly execute commands on the given EditingDomain to edit the feature. The commands should be created using the command factory. For example:

ICommandFactory commandFactory = ICommandFactoriesRegistry.INSTANCE.getCommandFactoryFor(editingDomain);
Command removeCommand = commandFactory.createRemoveCommand(editingDomain, eObject, feature, element);

model

Once you have implemented your cell editors, you can reference them in a celleditors model:

extension point

Then, use the celleditors extension point to register a model of cell editors. For example:

<extension point="org.eclipse.emf.facet.widgets.celleditors.celleditors">
  <cellEditorsModel path="my.modelcelleditors"/>
</extension>

example

For a full working example, you can look at plug-in org.eclipse.emf.facet.widgets.celleditors.ecore.

How to register custom Command factories

If you are using a specific editing domain that requires custom Commands, you can register a Command factory:

Copyright © 2010, 2012 CEA LIST. 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: Nicolas Bros (Mia-Software) Nicolas Guyomar (Mia-Software) Gregoire Dupe (Mia-Software) - Bug 388422 - Queries for InstanciationMethod needs to have 2 parameters