Home » Modeling » EMF "Technology" (Ecore Tools, EMFatic, etc) » [EEF] Recipe for incorporating related views
| | | | |
Re: [EEF] Recipe for incorporating related views [message #622224 is a reply to message #622119] |
Wed, 24 February 2010 19:50 |
Miles Parker 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 |
Goulwen Le Fur 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
|
|
|
Goto Forum:
Current Time: Thu Apr 25 05:09:33 GMT 2024
Powered by FUDForum. Page generated in 0.03284 seconds
|