Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » Proper way to add custom property editor
Proper way to add custom property editor [message #390477] Fri, 14 January 2005 20:41 Go to next message
Eric Giguere is currently offline Eric GiguereFriend
Messages: 58
Registered: July 2009
Member
Hi all

I've been reading for a while concerning the PropertySheet view and the
editors. I found the EMF class responsible for the custom editors we see
while editing an ecore model. Nice implementation but a little complex.

So from what I've understood, the class AdapterFactoryContentProvider is
the root of it all for EMF. This guy create an EMF specific PropertySource
which in turn creates an EMF specific PropertyDescriptor object. The later
is responsible for creating the right editor based on the type of item
selected in the Properties view using the method : getEditor.

Since I don't fully understand the mechanism through wich all these
factories are loaded and used by the framework (but I'll get it) what
would be the better way to add a new editor that would trig a an
EDataType? For some context info. I'm building extended models and while
doing so, I add attributes that will hold some specification text. Editing
text using the default string editor is not very practical so instead, I
want to create a simple property editor that will present a TextArea
instead of the embedded single line string editor.

How do we include custom PropertyDescriptors? Through the adapterFactory
object created in our editor?

thx for any pointers.
Eric.
Re: Proper way to add custom property editor [message #390480 is a reply to message #390477] Sat, 15 January 2005 16:37 Go to previous messageGo to next message
Joël Cheuoua is currently offline Joël CheuouaFriend
Messages: 36
Registered: July 2009
Member
Hello Eric,

I agree with you that this is not the easier part when using/customizing
EMF.
I think the answer is already somewhere in this newsgroups, but I'll try
to summarize it with what I understood, and give you my 2 cents tips.

Basically, as you already noticed, you'll need three things : The
ContentProvider, The PropertySource and The PropertyDescriptor. It may
sound cumbersome, but this is actually the finest way to control the
edition :

ContentProvider <=> provide property source for all model instances
PropertySource <=> on a model instance provide property descriptors for
all features
PropertyDescriptors <=> on an instance feature, control the
rendering/edition of the instance's feature value.

Here are the basic steps to go :

1 ) - You need to ammend your generated Editor Class : Check for the
getPropertySheetPage() method in this class, and change the
AdapterFactoryContentProvider PropertySourceProvider setted on the the
propertySheetPage to a CustomAdapterFactoryContentProvider class that
you'll create.

2 ) - Create the CustomAdapterFactoryContentProvider : It may basically be
as simple as this :

/**
* @author Joël
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class ModelMappingAdapterFactoryContentProvider extends
AdapterFactoryContentProvider {

/**
* @param adapterFactory
*/
public CustomAdapterFactoryContentProvider(AdapterFactory
adapterFactory) {
super(adapterFactory);
}

/*
* @see
AdapterFactoryContentProvider#createPropertySource(java.lang .Object,
* org.eclipse.emf.edit.provider.IItemPropertySource)
*/
protected IPropertySource createPropertySource(Object object,
IItemPropertySource itemPropertySource) {
return new CustomPropertySource(adapterFactory, object,
itemPropertySource);
}
}

3 ) Create the CustomPropertySource class that may look like this :

/**
* @author Joël
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class CustomPropertySource extends PropertySource {
private AdapterFactory adapterFactory;
/**
* @param object
* @param itemPropertySource
*/
public CustomPropertySource(AdapterFactory adapterFactory, Object
object, IItemPropertySource itemPropertySource) {
super(object, itemPropertySource);
this.adapterFactory = adapterFactory;
}

/*
* @see
PropertySource#createPropertyDescriptor(org.eclipse.emf.edit .provider.IItemPropertyDescriptor)
*/
protected IPropertyDescriptor
createPropertyDescriptor(IItemPropertyDescriptor itemPropertyDescriptor) {
return new CustomPropertyDescriptor(adapterFactory, object,
itemPropertyDescriptor);
}
}

4 ) Then create the CustomPropertyDescriptor class :

/**
* @author Joël
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class CustomPropertyDescriptor extends PropertyDescriptor {

private AdapterFactory adapterFactory;
/**
* @param object
* @param itemPropertyDescriptor
*/
public CustomPropertyDescriptor(AdapterFactory adapterFactory, Object
object, IItemPropertyDescriptor itemPropertyDescriptor) {
super(object, itemPropertyDescriptor);
this.adapterFactory = adapterFactory;
}

/*
* (non-Javadoc)
*
* @see
org.eclipse.ui.views.properties.IPropertyDescriptor#createPr opertyEditor(org.eclipse.swt.widgets.Composite)
*/
public CellEditor createPropertyEditor(Composite composite) {
Object feature = itemPropertyDescriptor.getFeature(object);
if (feature == /* TODO : Some file type kind feature */) {
final String dialogLabel =
CustomEMFPlugin.INSTANCE.getString("_UI_SelectFile_label");
CellEditor cellEditor = new DialogCellEditor(composite) {
protected Object openDialogBox(Control cellEditorWindow) {
ResourceSelectionDialog resourceSelectionDialog= new
ResourceSelectionDialog(cellEditorWindow
.getShell(), ResourcesPlugin.getWorkspace().getRoot(),
dialogLabel);
resourceSelectionDialog.open();
Object[] result = resourceSelectionDialog.getResult();
if (result != null) {
for (int i = 0; i < result.length; i++) {
if (result[i] instanceof IResource) {
IResource resource = (IResource) result[i];
return resource.getFullPath().toString();
}
}
}
return null;
}
};
return cellEditor;
}
return super.createPropertyEditor(composite);
}

At that point, you'll probably wonder why I pass the adapter factory as a
parameter to the CustomPropertySource and CustomPropertyDescriptor whereas
I don't use them and moreover the default implementation didn't do that ?

Well this is because - to my humble opinion - here could be several right
places to simplify the whole mechanism, at least for the EMF user point of
view, and make the Customxxx classes more generic : The adapterFactory
object is an adapter factory right ? - sounds like a "lapalissade" like we
said in France ;). So the property source, the property descriptor, and/or
more simply the cell editor can be adapters returned by the
adapterFactory.adapt(Object object, Object type) method instead of
creating a static instance each time in the createXXX methods.

It's up to you to choose how you may want to use this adapterFactory. At a
first glance, the easiest way seems to use what is already done for the
generated ItemProvider classes : You can amend ItemProvider classes so
that they return cell editor descriptors for defined features, and get
access to the Item providers by calling adapt() on the adapterFactory.

Of course for now you'll have to do the custom classes creation "by hand"
at least once, and you'll have to be careful that the code generation
didn't get rid of your customizations especially for the editor class. You
can also modify the JET Templates so that the generated code will reflect
all the changes :

1 ) changes to the Editor Class (custom contentprovider)
2 ) changes to the Item Provider Classes (methods for returnin
PropertyDescriptors/CellEditors given a feature)

I hope this can help.

Joel.


Eric Giguère wrote:

> Hi all

> I've been reading for a while concerning the PropertySheet view and the
> editors. I found the EMF class responsible for the custom editors we see
> while editing an ecore model. Nice implementation but a little complex.

> So from what I've understood, the class AdapterFactoryContentProvider is
> the root of it all for EMF. This guy create an EMF specific PropertySource
> which in turn creates an EMF specific PropertyDescriptor object. The later
> is responsible for creating the right editor based on the type of item
> selected in the Properties view using the method : getEditor.

> Since I don't fully understand the mechanism through wich all these
> factories are loaded and used by the framework (but I'll get it) what
> would be the better way to add a new editor that would trig a an
> EDataType? For some context info. I'm building extended models and while
> doing so, I add attributes that will hold some specification text. Editing
> text using the default string editor is not very practical so instead, I
> want to create a simple property editor that will present a TextArea
> instead of the embedded single line string editor.

> How do we include custom PropertyDescriptors? Through the adapterFactory
> object created in our editor?

> thx for any pointers.
> Eric.
Re: Proper way to add custom property editor [message #390493 is a reply to message #390480] Tue, 18 January 2005 16:27 Go to previous message
Eric Giguere is currently offline Eric GiguereFriend
Messages: 58
Registered: July 2009
Member
eheh
Thx a lot Joel
I'll try that tonight ;)

And yes, that part is not the easiest to pick but I'm getting there.
Eclipse is a quite complexe platform... but complexity comes with power in
our work so...

thx again.
Eric.

Joel Cheuoua wrote:

> Hello Eric,

> I agree with you that this is not the easier part when using/customizing
> EMF.
> I think the answer is already somewhere in this newsgroups, but I'll try
> to summarize it with what I understood, and give you my 2 cents tips.

> Basically, as you already noticed, you'll need three things : The
> ContentProvider, The PropertySource and The PropertyDescriptor. It may
> sound cumbersome, but this is actually the finest way to control the
> edition :

> ContentProvider <=> provide property source for all model instances
> PropertySource <=> on a model instance provide property descriptors for
> all features
> PropertyDescriptors <=> on an instance feature, control the
> rendering/edition of the instance's feature value.

> Here are the basic steps to go :

> 1 ) - You need to ammend your generated Editor Class : Check for the
> getPropertySheetPage() method in this class, and change the
> AdapterFactoryContentProvider PropertySourceProvider setted on the the
> propertySheetPage to a CustomAdapterFactoryContentProvider class that
> you'll create.

> 2 ) - Create the CustomAdapterFactoryContentProvider : It may basically be
> as simple as this :

> /**
> * @author Joël
> *
> * TODO To change the template for this generated type comment go to
> * Window - Preferences - Java - Code Style - Code Templates
> */
> public class ModelMappingAdapterFactoryContentProvider extends
> AdapterFactoryContentProvider {

> /**
> * @param adapterFactory
> */
> public CustomAdapterFactoryContentProvider(AdapterFactory
> adapterFactory) {
> super(adapterFactory);
> }

> /*
> * @see
> AdapterFactoryContentProvider#createPropertySource(java.lang .Object,
> * org.eclipse.emf.edit.provider.IItemPropertySource)
> */
> protected IPropertySource createPropertySource(Object object,
> IItemPropertySource itemPropertySource) {
> return new CustomPropertySource(adapterFactory, object,
> itemPropertySource);
> }
> }

> 3 ) Create the CustomPropertySource class that may look like this :

> /**
> * @author Joël
> *
> * TODO To change the template for this generated type comment go to
> * Window - Preferences - Java - Code Style - Code Templates
> */
> public class CustomPropertySource extends PropertySource {
> private AdapterFactory adapterFactory;
> /**
> * @param object
> * @param itemPropertySource
> */
> public CustomPropertySource(AdapterFactory adapterFactory, Object
> object, IItemPropertySource itemPropertySource) {
> super(object, itemPropertySource);
> this.adapterFactory = adapterFactory;
> }

> /*
> * @see
>
PropertySource#createPropertyDescriptor(org.eclipse.emf.edit .provider.IItemPropertyDescriptor)
> */
> protected IPropertyDescriptor
> createPropertyDescriptor(IItemPropertyDescriptor itemPropertyDescriptor) {
> return new CustomPropertyDescriptor(adapterFactory, object,
> itemPropertyDescriptor);
> }
> }

> 4 ) Then create the CustomPropertyDescriptor class :

> /**
> * @author Joël
> *
> * TODO To change the template for this generated type comment go to
> * Window - Preferences - Java - Code Style - Code Templates
> */
> public class CustomPropertyDescriptor extends PropertyDescriptor {

> private AdapterFactory adapterFactory;
> /**
> * @param object
> * @param itemPropertyDescriptor
> */
> public CustomPropertyDescriptor(AdapterFactory adapterFactory, Object
> object, IItemPropertyDescriptor itemPropertyDescriptor) {
> super(object, itemPropertyDescriptor);
> this.adapterFactory = adapterFactory;
> }

> /*
> * (non-Javadoc)
> *
> * @see
>
org.eclipse.ui.views.properties.IPropertyDescriptor#createPr opertyEditor(org.eclipse.swt.widgets.Composite)
> */
> public CellEditor createPropertyEditor(Composite composite) {
> Object feature = itemPropertyDescriptor.getFeature(object);
> if (feature == /* TODO : Some file type kind feature */) {
> final String dialogLabel =
> CustomEMFPlugin.INSTANCE.getString("_UI_SelectFile_label");
> CellEditor cellEditor = new DialogCellEditor(composite) {
> protected Object openDialogBox(Control cellEditorWindow) {
> ResourceSelectionDialog resourceSelectionDialog= new
> ResourceSelectionDialog(cellEditorWindow
> .getShell(), ResourcesPlugin.getWorkspace().getRoot(),
> dialogLabel);
> resourceSelectionDialog.open();
> Object[] result = resourceSelectionDialog.getResult();
> if (result != null) {
> for (int i = 0; i < result.length; i++) {
> if (result[i] instanceof IResource) {
> IResource resource = (IResource) result[i];
> return resource.getFullPath().toString();
> }
> }
> }
> return null;
> }
> };
> return cellEditor;
> }
> return super.createPropertyEditor(composite);
> }

> At that point, you'll probably wonder why I pass the adapter factory as a
> parameter to the CustomPropertySource and CustomPropertyDescriptor whereas
> I don't use them and moreover the default implementation didn't do that ?

> Well this is because - to my humble opinion - here could be several right
> places to simplify the whole mechanism, at least for the EMF user point of
> view, and make the Customxxx classes more generic : The adapterFactory
> object is an adapter factory right ? - sounds like a "lapalissade" like we
> said in France ;). So the property source, the property descriptor, and/or
> more simply the cell editor can be adapters returned by the
> adapterFactory.adapt(Object object, Object type) method instead of
> creating a static instance each time in the createXXX methods.

> It's up to you to choose how you may want to use this adapterFactory. At a
> first glance, the easiest way seems to use what is already done for the
> generated ItemProvider classes : You can amend ItemProvider classes so
> that they return cell editor descriptors for defined features, and get
> access to the Item providers by calling adapt() on the adapterFactory.

> Of course for now you'll have to do the custom classes creation "by hand"
> at least once, and you'll have to be careful that the code generation
> didn't get rid of your customizations especially for the editor class. You
> can also modify the JET Templates so that the generated code will reflect
> all the changes :

> 1 ) changes to the Editor Class (custom contentprovider)
> 2 ) changes to the Item Provider Classes (methods for returnin
> PropertyDescriptors/CellEditors given a feature)

> I hope this can help.

> Joel.


> Eric Giguère wrote:

>> Hi all

>> I've been reading for a while concerning the PropertySheet view and the
>> editors. I found the EMF class responsible for the custom editors we see
>> while editing an ecore model. Nice implementation but a little complex.

>> So from what I've understood, the class AdapterFactoryContentProvider is
>> the root of it all for EMF. This guy create an EMF specific PropertySource
>> which in turn creates an EMF specific PropertyDescriptor object. The later
>> is responsible for creating the right editor based on the type of item
>> selected in the Properties view using the method : getEditor.

>> Since I don't fully understand the mechanism through wich all these
>> factories are loaded and used by the framework (but I'll get it) what
>> would be the better way to add a new editor that would trig a an
>> EDataType? For some context info. I'm building extended models and while
>> doing so, I add attributes that will hold some specification text. Editing
>> text using the default string editor is not very practical so instead, I
>> want to create a simple property editor that will present a TextArea
>> instead of the embedded single line string editor.

>> How do we include custom PropertyDescriptors? Through the adapterFactory
>> object created in our editor?

>> thx for any pointers.
>> Eric.
Previous Topic:Trouble with JET
Next Topic:Generating XSD aware SDO from XSD and XML document
Goto Forum:
  


Current Time: Mon Mar 01 09:13:36 GMT 2021

Powered by FUDForum. Page generated in 0.02970 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top