Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » Notifying container of its child's feature changes
Notifying container of its child's feature changes [message #426617] Thu, 15 January 2009 16:25 Go to next message
AJ  is currently offline AJ Friend
Messages: 77
Registered: July 2009
Member
I have an object A which has an 1 to many containment reference to object
B. I would like the getImage method of A to be called when a feature
attribute of B is changed. So, is there a way to notify B's container?

TIA!
Re: Notifying container of its child's feature changes [message #426625 is a reply to message #426617] Thu, 15 January 2009 18:54 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33218
Registered: July 2009
Senior Member
Ben,

You can have an adapter on A that attaches adapters to any B that's
added to A. EContentAdapter.handleContainment will give you the idea of
how to process notifications on A that add/remove/set B values and then
you can process B events. If this question is more focused on the item
providers in a tree view, you could look at
EGenericTypeItemProvider.notifyChanged to see how notifications on a
child are easily propagated to look like notification on the parent so
that both the child label and the parent's label are recomputed.


Ben wrote:
> I have an object A which has an 1 to many containment reference to
> object B. I would like the getImage method of A to be called when a
> feature attribute of B is changed. So, is there a way to notify B's
> container?
>
> TIA!
>


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Notifying container of its child's feature changes [message #426638 is a reply to message #426625] Fri, 16 January 2009 03:04 Go to previous messageGo to next message
AJ  is currently offline AJ Friend
Messages: 77
Registered: July 2009
Member
Ed,

Correct, the latter (EGenericTypeItemProvider.notifyChanged) seem be the
best approach for me. However, I added the code below into the
BItemProvider, but its container A never gets the notification.

I also tried this EMF-Recipe:
http://wiki.eclipse.org/EMF/Recipes#Recipe:_Custom_Labels

And although the ChangeListener inner class receives the notification, it
is never propagated to the notifyChanged method in the AItemProvider.

Currently, A is stateful and B singleton, but even when I change both to
either stateful or singleton, it still does not work. Any suggestions?
Thanks Ed!


-----------------------------------------------------
---------- EGenericTypeItemProvider approach --------
-----------------------------------------------------
public void notifyChanged(Notification notification) {
updateChildren(notification);

switch (notification.getFeatureID(CommonMember.class)) {
case PlanPackage.COMMON_MEMBER__NOTES:
case PlanPackage.COMMON_MEMBER__VISIBLE:
case PlanPackage.COMMON_MEMBER__COLOR:
fireNotifyChanged(new ViewerNotification(notification,
notification.getNotifier(), false, true));
for (EObject container =
((EObject)notification.getNotifier()).eContainer(); container != null;
container = container.eContainer())
{
fireNotifyChanged(new ViewerNotification(notification,
container, false, true));
if (container instanceof EOperation || container instanceof
EStructuralFeature || container instanceof EClassifier)
{
break;
}
}
return;
case PlanPackage.COMMON_MEMBER__MARKED:
fireNotifyChanged(new ViewerNotification(notification,
notification.getNotifier(), false, true));
return;
}
super.notifyChanged(notification);
}
Re: Notifying container of its child's feature changes [message #426639 is a reply to message #426638] Fri, 16 January 2009 03:26 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33218
Registered: July 2009
Senior Member
Ben,

Comments below.

Ben wrote:
> Ed,
>
> Correct, the latter (EGenericTypeItemProvider.notifyChanged) seem be
> the best approach for me. However, I added the code below into the
> BItemProvider, but its container A never gets the notification.
If this is done at the item provider level, the container itself never
sees notifications. It's the view watching the container that gets told
the container's label needs updating...
>
> I also tried this EMF-Recipe:
> http://wiki.eclipse.org/EMF/Recipes#Recipe:_Custom_Labels
>
> And although the ChangeListener inner class receives the notification,
> it is never propagated to the notifyChanged method in the AItemProvider.
It's not supposed to...
>
> Currently, A is stateful and B singleton, but even when I change both
> to either stateful or singleton, it still does not work. Any
> suggestions? Thanks Ed!
>
>
> -----------------------------------------------------
> ---------- EGenericTypeItemProvider approach --------
> -----------------------------------------------------
> public void notifyChanged(Notification notification) {
> updateChildren(notification);
>
> switch (notification.getFeatureID(CommonMember.class)) {
> case PlanPackage.COMMON_MEMBER__NOTES:
> case PlanPackage.COMMON_MEMBER__VISIBLE:
> case PlanPackage.COMMON_MEMBER__COLOR:
> fireNotifyChanged(new ViewerNotification(notification,
> notification.getNotifier(), false, true));
> for (EObject container =
> ((EObject)notification.getNotifier()).eContainer(); container != null;
> container = container.eContainer())
> {
> fireNotifyChanged(new
> ViewerNotification(notification, container, false, true));
See the idea here is that the original notification is made to look like
a label update for the container. The container's item provider will
not see this. Only the viewer will see this...

So is this being called where container is the A object? If so, then
A's getImage and getText should be called...
> if (container instanceof EOperation || container
> instanceof EStructuralFeature || container instanceof EClassifier)
This is a bogus condition for your model, right?
> { break;
> }
> }
> return;
> case PlanPackage.COMMON_MEMBER__MARKED:
> fireNotifyChanged(new ViewerNotification(notification,
> notification.getNotifier(), false, true));
> return;
> }
> super.notifyChanged(notification);
> }
>


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Notifying container of its child's feature changes [message #426640 is a reply to message #426639] Fri, 16 January 2009 06:14 Go to previous messageGo to next message
AJ  is currently offline AJ Friend
Messages: 77
Registered: July 2009
Member
Ed,

Yes, it is done at the BItemProvider level and when I referred to the
container, I meant that the AItemProvider was not receiving the
notification.

Anyway, I used our best friend, "the debuger", and I noticed that the
fireNotifyChanged method in the BItemProvider calls fireNotifyChanged in
the ItemProviderAdapter class. However, changeNotifier is null so
(IChangeNotifier)adapterFactory is assigned to changeNotifier. Is that
okay?

Also, I failed to mentioned that my view is actually a FormPart where I
have attached an adapter to the container/input object as shown below. The
notifyChanged method in the adapter is called when A's attributes are
changed, but it is still not called when the B's color attribute is
changed.

So please let me know if you any suggestion or if you want me to debug
into something in particular. Thanks again Ed!


private class AdapterImpl implements Adapter {
...
....
public void notifyChanged(Notification notification) {
if (input == notification.getNotifier() && notification instanceof
ENotificationImpl) {
WidgetUtils.runInDisplayThread(titleComposite, new Runnable() {
public void run() {
refresh();
}
});
}
}
}
Re: Notifying container of its child's feature changes [message #426651 is a reply to message #426640] Fri, 16 January 2009 12:16 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33218
Registered: July 2009
Senior Member
Ben,

Comments below.

Ben wrote:
> Ed,
>
> Yes, it is done at the BItemProvider level and when I referred to the
> container, I meant that the AItemProvider was not receiving the
> notification.
It's not supposed to though. It only gets notifications for feature
changes to A... It's not designed to handle notifications from other
types of objects...
>
> Anyway, I used our best friend, "the debuger", and I noticed that the
> fireNotifyChanged method in the BItemProvider calls fireNotifyChanged
> in the ItemProviderAdapter class. However, changeNotifier is null so
> (IChangeNotifier)adapterFactory is assigned to changeNotifier. Is that
> okay?
Should this last statement block of the implementation not suffice?

if (adapterFactory instanceof IChangeNotifier)
{
IChangeNotifier changeNotifier = (IChangeNotifier)adapterFactory;
changeNotifier.fireNotifyChanged(notification);
}
>
> Also, I failed to mentioned that my view is actually a FormPart where
> I have attached an adapter to the container/input object as shown below.
You did. :-P
> The notifyChanged method in the adapter is called when A's attributes
> are changed, but it is still not called when the B's color attribute
> is changed.
>
> So please let me know if you any suggestion or if you want me to debug
> into something in particular. Thanks again Ed!
Take a different approach then. The B knows the A, so when you get a
notification on the B, create an ENotification for a change to A exactly
like the one that's generated if you set A. Or perhaps simpler still
call a.setImage(a.getImage())...

Are you using a label provider and listening too it. That would be a
better approach, because then the view could listen and see the viewer
notifications...
>
>
> private class AdapterImpl implements Adapter {
> ...
> ....
> public void notifyChanged(Notification notification) {
> if (input == notification.getNotifier() && notification instanceof
> ENotificationImpl) {
Why the ENotificationImpl test? Trying to filter out the
ViewerNotifications?
> WidgetUtils.runInDisplayThread(titleComposite, new Runnable() {
> public void run() {
> refresh();
> }
> });
> }
> }
> }
>


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Notifying container of its child's feature changes [message #426674 is a reply to message #426651] Fri, 16 January 2009 23:04 Go to previous messageGo to next message
AJ  is currently offline AJ Friend
Messages: 77
Registered: July 2009
Member
Thanks Ed!

Using the label provider approach worked best for me.

private ILabelProvider getLabelProvider(Object input) {
AdapterFactory factory = getAdapterFactory(input);
return factory == null ? null : new AdapterFactoryLabelProvider(factory)
{
public void notifyChanged(Notification notification) {
if (notification instanceof ViewerNotification &&
((ViewerNotification) notification).isLabelUpdate()) {
WidgetUtils.runInDisplayThread(titleComposite, new Runnable() {
public void run() {
refresh();
}
});
}
}
};
}
Re: Notifying container of its child's feature changes [message #426676 is a reply to message #426674] Fri, 16 January 2009 23:48 Go to previous message
AJ  is currently offline AJ Friend
Messages: 77
Registered: July 2009
Member
Sorry, I spoke ahead of myself. The ENotification approach works best for
me. :-)
Previous Topic:IndexOutOfBoundsException
Next Topic:[Teneo] resource utility / property editor: cannot edit collection fields
Goto Forum:
  


Current Time: Tue Sep 24 21:12:51 GMT 2024

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

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

Back to the top