Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF "Technology" (Ecore Tools, EMFatic, etc)  » [EEF] Recipe for incorporating related views
[EEF] Recipe for incorporating related views [message #622119] Thu, 11 February 2010 00:25 Go to next message
Miles Parker is currently offline Miles ParkerFriend
Messages: 1341
Registered: July 2009
Senior Member
Hi,

I've got two related scenarios that I'm wondering if EEF can accommodate now.

1. I have EClasses that have a cardinality 1-0 containment relationship to another class. I'd like to include those in the editor as-if they were in the same view.

2. Is there a recipe for doing Master-Detail views? Or is this not supported (yet)?

Also, I'm wondering if I have this usage pattern correct. Since EEF doesn't support subclassing OOTB, what I'd like to do is break the shared references and attributes into a separate view and then include that view with each of the sub EClasses. Is that a sensible thing to do?

thanks!

Miles
Re: [EEF] Recipe for incorporating related views [message #622145 is a reply to message #622119] Mon, 15 February 2010 14:41 Go to previous messageGo to next message
Goulwen Le Fur is currently offline Goulwen Le FurFriend
Messages: 125
Registered: July 2009
Senior Member
Hi again :)

We have already done it for a customer but we used a "Custom Element
Editor" and we made all is necessary in the User Code. So we can't
really say that EEF can handle it but ... there a way to do that ;)

--
Goulwen Le Fur - goulwen.lefur@obeo.fr

Miles Parker a écrit :
> Hi,
>
> I've got two related scenarios that I'm wondering if EEF can accommodate
> now.
>
> 1. I have EClasses that have a cardinality 1-0 containment relationship
> to another class. I'd like to include those in the editor as-if they
> were in the same view.
> 2. Is there a recipe for doing Master-Detail views? Or is this not
> supported (yet)?
>
> Also, I'm wondering if I have this usage pattern correct. Since EEF
> doesn't support subclassing OOTB, what I'd like to do is break the
> shared references and attributes into a separate view and then include
> that view with each of the sub EClasses. Is that a sensible thing to do?
>
> thanks!
>
> Miles
Re: [EEF] Recipe for incorporating related views [message #622150 is a reply to message #622145] Tue, 16 February 2010 04:22 Go to previous messageGo to next message
Miles Parker is currently offline Miles ParkerFriend
Messages: 1341
Registered: July 2009
Senior Member
Goulwen Le Fur wrote on Mon, 15 February 2010 04:44
> Hi again :)
>
> We have already done it for a customer but we used a "Custom Element
> Editor" and we made all is necessary in the User Code. So we can't
> really say that EEF can handle it but ... there a way to do that ;)


OK, can I please have a hint? :) I have a demo I'd like to do and I'm just not grokking the process. All I need to be able to do is figure out some way to show two levels of detail at the same time. It seems like there should be a way to

a) use an Element Editor (advanced table composition?) for a list of references

and

b) when the user clicks an element (or adds a new one) on the same form display the details for that attribute.

-Miles
Re: [EEF] Recipe for incorporating related views [message #622188 is a reply to message #622119] Tue, 23 February 2010 00:37 Go to previous messageGo to next message
Miles Parker is currently offline Miles ParkerFriend
Messages: 1341
Registered: July 2009
Senior Member
Bumping. :d

I am really finding myself stuck on this usage scenario. It's frustrating, because there seems to be a hint of how to do it in the user docs:

http://wiki.eclipse.org/EEF_User_Guide

But then it just kind of ends mid-stream.

To be clear, this is all I want to do.. in the case where I have a containment relationship, I'd like to show nested detail for a selected item somehow within the sub-form for the parent list. For example, I might have:

[Library of Congress]

Name:
Library of Congress

>Books:

[A very very long list...wit one item selected]

>>Name:

EEF Development for Fun and Profit
Re: [EEF] Recipe for incorporating related views [message #622191 is a reply to message #622188] Tue, 23 February 2010 09:08 Go to previous messageGo to next message
Goulwen Le Fur is currently offline Goulwen Le FurFriend
Messages: 125
Registered: July 2009
Senior Member
Sorry Miles, I was a bit busy these days :)

So, here is my "crappy" technique to obtain what you want :
- Generate all the EEF artifact for Book metaclass (components, parts,
properties ...)
- Add a CustomElementEditor (and the associated
PropertiesEditionElement) in the view of Library you want to display
books on
- Generates. There will be "User Code" everywhere in the Library EEF
classes. You need to customize it.
- Add the result of the EEF generation for Book in these "User Code".
And voila ! ;)

Try this process and let me know if you encounter troubles ;)

--

Goulwen Le Fur - goulwen.lefur@obeo.fr

Miles Parker a écrit :
> Bumping. :d
>
> I am really finding myself stuck on this usage scenario. It's
> frustrating, because there seems to be a hint of how to do it in the
> user docs:
>
> http://wiki.eclipse.org/EEF_User_Guide
>
> But then it just kind of ends mid-stream.
>
> To be clear, this is all I want to do.. in the case where I have a
> containment relationship, I'd like to show nested detail for a selected
> item somehow within the sub-form for the parent list. For example, I
> might have:
>
> [Library of Congress]
> Name:
> Library of Congress
>
>> Books:
>
> [A very very long list...wit one item selected]
>
>>> Name:
>
> EEF Development for Fun and Profit
>
>
>
>
Re: [EEF] Recipe for incorporating related views [message #622224 is a reply to message #622119] Wed, 24 February 2010 19:50 Go to previous messageGo to next message
Miles Parker is currently offline Miles ParkerFriend
Messages: 1341
Registered: July 2009
Senior Member
OK, thanks Goulwen, that was exactly what I needed and gave me the confidence that I was headed in the right direction. I spent yesterday getting this up and running and so here's the more involved recipe. Ce n'est pas de la tarte! But not too difficult either..


In Repository for Library, add a Custom Element editor for "bookDetail".
In Properties Edition for "Library", added a "bookDetail" that uses that view. I set the model to "books" because it needs to be bound to something, I think.
Generated the code.
Changed a bunch of code. (I'm only covering the forms stuff here as I don't need the regular parts for my usage.) My basic strategy was to delegate to the corresponding Book classes rather than copy the code whenever possible.
In In LibraryPropertiesEditionPartForm

protected void createBooksTableComposition(FormToolkit widgetFactory, Composite parent) {
// Start of user code for additional ui definition
this.attributes.addSelectionListener(new SelectionListener() {

public void widgetSelected(SelectionEvent e) {
if (e.item != null) {
Object data = e.item.getData();
if (data instanceof Book) {
if (e.item != null && e.item.getData() instanceof EObject) {
EObject attr = attributesEditUtil.foundCorrespondingEObject((EObject) e.item.getData());
setCurrentAttribute((Book) attr);
return;
}
}
}
setCurrentAttribute(null);
}

public void widgetDefaultSelected(SelectionEvent e) {
}
});
// End of user code
This was my biggest hangup, because I didn't know that I needed to use the utility to find a different corresponding eObject. If I'd have figured that out, it would have been much quicker. Also, I think that I may not be doing this in the best way. I noticed in the Tarot example that you used a fireProperties instead of setting the values explicitly, but I couldn't easily make that work.
Instead I created this method:

private void setCurrentAttribute(Book book) {
((LibraryPropertiesEditionComponent) propertiesEditionComponent).setbook(book);
attributesComponent.setLiveEditingDomain(((LibraryProperties EditionComponent) propertiesEditionComponent)
.getLiveDomain());
((LibraryPropertiesEditionComponent) propertiesEditionComponent).setbookProps(attributesComponent );
attributesComponent.setPropertiesEditionPart(MetaabmViewsRep ository.Book.class, 0, attributesForm);
attributesComponent.addListener(attributesForm);
attributesComponent.addListener(this);
attributesComponent.setAttribute(book);
if (book != null) {
attributesComponent.initPart(MetaabmViewsRepository.Book.cla ss, 0, book, resourceSet);
} else {
attributesComponent.initPart(MetaabmViewsRepository.Book.cla ss, 0, null, resourceSet);
}
}

protected void createBooksGroup(FormToolkit widgetFactory, final Composite view) {

// Start of user code for attributeDetail widgets implementation
GridData attributesGroupData2 = new GridData(SWT.FILL, SWT.TOP, true, false);
attributesForm.createDetailsGroup(widgetFactory, attributesGroup, Section.TITLE_BAR | Section.TWISTIE
| Section.EXPANDED);
attributesForm.getDetailsSection().setLayoutData(attributesG roupData2);
attributesComponent = new BookPropertiesEditionComponent(null, IPropertiesEditionComponent.LIVE_MODE);
// End of user code



In In BookPropertiesEditionPartForm:

Changed the constructor to break out the book setting to a seperate setter, like so:


/**
* Default constructor
*/
public BookPropertiesEditionComponent(EObject book, String editing_mode) {
this.editing_mode = editing_mode;
setAttribute((Book) book);
}

public void setAttribute(Book attr) {
if (book != null) {
this.book.eAdapters().remove(semanticAdapter);
}
this.book = attr;
if (book != null) {
if (IPropertiesEditionComponent.LIVE_MODE.equals(editing_mode)) {
if (semanticAdapter == null) {
semanticAdapter = initializeSemanticAdapter();
}
this.book.eAdapters().add(semanticAdapter);
}
}
}
This let's me use it to set domain object independently. Perhaps there is a better way to do this, but the issue is that I want to be able to reuse the component if possible.

In LibraryPropertiesEditionComponent -- these are the most important!

Added the following fields and methods:
// Start of user code for attributeDetail properties

private Book book;

private BookPropertiesEditionComponent bookProps;
/**
* @param book the book to set
*/
public void setbook(Book book) {
this.book = book;
}

/**
* @param bookProps the bookProps to set
*/
public void setbookProps(BookPropertiesEditionComponent bookProps) {
this.bookProps = bookProps;
}

public EditingDomain getLiveDomain() {
return liveEditingDomain;
}

// End of user code

(The generator is not protecting my user code here for some reason, so I need to figure that out..) The point of this is that I need to keep a reference to the detail component and the detail domain object in the parent component. Or at least I think I do, perhaps there is a more clever way to do this.
In protected void runUpdateRunnable(final Notification msg) {
// Start of user code for attributeDetail live update
if (msg.getNotifier() == book) {
bookProps.runUpdateRunnable(msg);
basePart.updateAttributes(library);
}
// End of user code

In public CompoundCommand getPropertiesEditionCommand(EditingDomain editingDomain) {

// Start of user code for attributeDetail update command
if (book != null) {
CompoundCommand attrEditionCommand = bookProps.getPropertiesEditionCommand(editingDomain);
cc.append(attrEditionCommand);
}

// End of user code

In public EObject getPropertiesEditionObject(EObject source) {

// Start of user code for attributeDetail part update
if (book != null) {
bookProps.getPropertiesEditionObject(book);
}
// End of user code

In public void firePropertiesChanged(IPropertiesEditionEvent event) {

// Start of user code for attributeDetail live command update
if (book != null && event.getAffectedEditor().startsWith("metaabm::Book")) {
bookProps.firePropertiesChanged(event);
}

// End of user code






That's it! :) But I have probably missed something here.. hope it helps some other folks who might need to do this.

BTW, something that could be a translation issue, or may just be my not understanding all of the design yet, but does "Edition" in this context mean "a particular version / instantiation of something" or "something that is used for editing"? If the latter then the word doesn't quite mean that. It might be more clear as "Editing" or simply "Edit", so for example we would have "Property Editing Component" and "LibraryPropertiesEditPartForm".
Re: [EEF] Recipe for incorporating related views [message #622229 is a reply to message #622224] Thu, 25 February 2010 09:01 Go to previous message
Goulwen Le Fur is currently offline Goulwen Le FurFriend
Messages: 125
Registered: July 2009
Senior Member
Hi Miles,

Miles Parker a écrit :
> OK, thanks Goulwen, that was exactly what I needed and gave me the
> confidence that I was headed in the right direction. I spent yesterday
> getting this up and running and so here's the more involved recipe. Ce
> n'est pas de la tarte! But not too difficult either..
>

huhu, I like your phrase ;)

>
> In Repository for Library, add a Custom Element editor for "bookDetail".
> In Properties Edition for "Library", added a "bookDetail" that uses that
> view. I set the model to "books" because it needs to be bound to
> something, I think.
> Generated the code.
> Changed a bunch of code. (I'm only covering the forms stuff here as I
> don't need the regular parts for my usage.) My basic strategy was to
> delegate to the corresponding Book classes rather than copy the code
> whenever possible.
> In In LibraryPropertiesEditionPartForm
>
> protected void createBooksTableComposition(FormToolkit widgetFactory,
> Composite parent) {
> // Start of user code for additional ui definition
> this.attributes.addSelectionListener(new SelectionListener() {
>
> public void widgetSelected(SelectionEvent e) {
> if (e.item != null) {
> Object data = e.item.getData();
> if (data instanceof Book) {
> if (e.item != null && e.item.getData() instanceof
> EObject) {
> EObject attr =
> attributesEditUtil.foundCorrespondingEObject((EObject) e.item.getData());
> setCurrentAttribute((Book) attr);
> return;
> }
> }
> }
> setCurrentAttribute(null);
> }
>
> public void widgetDefaultSelected(SelectionEvent e) {
> }
> });
> // End of user code
> This was my biggest hangup, because I didn't know that I needed to use
> the utility to find a different corresponding eObject. If I'd have
> figured that out, it would have been much quicker. Also, I think that I
> may not be doing this in the best way. I noticed in the Tarot example
> that you used a fireProperties instead of setting the values explicitly,
> but I couldn't easily make that work.
> Instead I created this method:
>
> private void setCurrentAttribute(Book book) {
> ((LibraryPropertiesEditionComponent)
> propertiesEditionComponent).setbook(book);
>
> attributesComponent.setLiveEditingDomain(((LibraryProperties EditionComponent)
> propertiesEditionComponent)
> .getLiveDomain());
> ((LibraryPropertiesEditionComponent)
> propertiesEditionComponent).setbookProps(attributesComponent );
>
> attributesComponent.setPropertiesEditionPart(MetaabmViewsRep ository.Book.class,
> 0, attributesForm);
> attributesComponent.addListener(attributesForm);
> attributesComponent.addListener(this);
> attributesComponent.setAttribute(book);
> if (book != null) {
>
> attributesComponent.initPart(MetaabmViewsRepository.Book.cla ss, 0, book,
> resourceSet);
> } else {
>
> attributesComponent.initPart(MetaabmViewsRepository.Book.cla ss, 0, null,
> resourceSet);
> }
> }
>
> protected void createBooksGroup(FormToolkit widgetFactory, final
> Composite view) {
>
> // Start of user code for attributeDetail widgets implementation
> GridData attributesGroupData2 = new GridData(SWT.FILL, SWT.TOP,
> true, false);
> attributesForm.createDetailsGroup(widgetFactory, attributesGroup,
> Section.TITLE_BAR | Section.TWISTIE
> | Section.EXPANDED);
>
> attributesForm.getDetailsSection().setLayoutData(attributesG roupData2);
> attributesComponent = new BookPropertiesEditionComponent(null,
> IPropertiesEditionComponent.LIVE_MODE);
> // End of user code
>
>
>
> In In BookPropertiesEditionPartForm:
>
> Changed the constructor to break out the book setting to a seperate
> setter, like so:
>
>
> /**
> * Default constructor
> */
> public BookPropertiesEditionComponent(EObject book, String
> editing_mode) {
> this.editing_mode = editing_mode;
> setAttribute((Book) book);
> }
>
> public void setAttribute(Book attr) {
> if (book != null) {
> this.book.eAdapters().remove(semanticAdapter);
> }
> this.book = attr;
> if (book != null) {
> if (IPropertiesEditionComponent.LIVE_MODE.equals(editing_mode)) {
> if (semanticAdapter == null) {
> semanticAdapter = initializeSemanticAdapter();
> }
> this.book.eAdapters().add(semanticAdapter);
> }
> }
> }
> This let's me use it to set domain object independently. Perhaps there
> is a better way to do this, but the issue is that I want to be able to
> reuse the component if possible.
>
> In LibraryPropertiesEditionComponent -- these are the most important!
>
> Added the following fields and methods:
> // Start of user code for attributeDetail properties
>
> private Book book;
>
> private BookPropertiesEditionComponent bookProps;
> /**
> * @param book the book to set
> */
> public void setbook(Book book) {
> this.book = book;
> }
>
> /**
> * @param bookProps the bookProps to set
> */
> public void setbookProps(BookPropertiesEditionComponent bookProps) {
> this.bookProps = bookProps;
> }
>
> public EditingDomain getLiveDomain() {
> return liveEditingDomain;
> }
>
> // End of user code
>
> (The generator is not protecting my user code here for some reason, so I
> need to figure that out..) The point of this is that I need to keep a
> reference to the detail component and the detail domain object in the
> parent component. Or at least I think I do, perhaps there is a more
> clever way to do this.
> In protected void runUpdateRunnable(final Notification msg) {
> // Start of user code for attributeDetail live update
> if (msg.getNotifier() == book) {
> bookProps.runUpdateRunnable(msg);
> basePart.updateAttributes(library);
> }
> // End of user code
>
> In public CompoundCommand getPropertiesEditionCommand(EditingDomain
> editingDomain) {
>
> // Start of user code for attributeDetail update command
> if (book != null) {
> CompoundCommand attrEditionCommand =
> bookProps.getPropertiesEditionCommand(editingDomain);
> cc.append(attrEditionCommand);
> }
>
> // End of user code
>
> In public EObject getPropertiesEditionObject(EObject source) {
>
> // Start of user code for attributeDetail part update
> if (book != null) {
> bookProps.getPropertiesEditionObject(book);
> }
> // End of user code
>
> In public void firePropertiesChanged(IPropertiesEditionEvent event) {
>
> // Start of user code for attributeDetail live command update
> if (book != null &&
> event.getAffectedEditor().startsWith("metaabm::Book")) {
> bookProps.firePropertiesChanged(event);
> }
>
> // End of user code
>
>
>
>
>
>
> That's it! :) But I have probably missed something here.. hope it helps
> some other folks who might need to do this.
>

It's great ! Can you put this process on the Eclipse Wiki ?

> BTW, something that could be a translation issue, or may just be my not
> understanding all of the design yet, but does "Edition" in this context
> mean "a particular version / instantiation of something" or "something
> that is used for editing"? If the latter then the word doesn't quite
> mean that. It might be more clear as "Editing" or simply "Edit", so for
> example we would have "Property Editing Component" and
> "LibraryPropertiesEditPartForm".

You're right, It's a translation issue but I'm not sure of the way to
fix it ! :) If we change the EEF metamodels we have to create a
migration tool for older version, the problem is the same for changes in
API (the User Code problem !). And if we just change labelProvider we
don't solve the problem. We just hide it ! ;)


--
Goulwen Le Fur - goulwen.lefur@obeo.fr
Previous Topic:Multiple ecore files with similar structure
Next Topic:[EEF] EEF architecture generation failed
Goto Forum:
  


Current Time: Thu Apr 25 05:09:33 GMT 2024

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

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

Back to the top