Live Updating View

Started by Whinard, July 19, 2017, 14:10:08 PM

Previous topic - Next topic

Whinard

Hello,

I am working on a plug-in where I want to update proprties in other elements in the view when a property is changed in one of the elements in the view. I am not looking for a detailed answer, because I understand it is rather complicated, just a direction to start with. I do not even know where to begin programming this into my plug-in.

All I have considered so far is a listener/handler, but I didn't quite know how to tie these in to a change in the code.

Any adviced in appreciated.

Whinard

I have also found the java classes Observer and Observable. The problem with this it that I would have to add it to the com.archimate.model.impl.Property class. If I update this class as part of my plugin, when I export my class, will this include the changes I made to the com.archimate.model.impl.Property class?

Phil Beauvoir

If you change any code outside of your plugin your plugin will not work in a standard installation of Archi. You'd have to re-build the whole app, so you shouldn't change core code.

You need to add a listener to the model and make changes in accordance with model events. If you do make changes to the model you also have to add these to the model's Undo/Redo Command stack so that the change is undone correctly on an Undo action.

But why do you want to update properties in other elements? If you give a detailed explanation of what and why you are doing this it would help.

Phil

If you value and use Archi, please consider making a donation!
Ask your ArchiMate related questions to the ArchiMate Community's Discussion Board.

Whinard

I am attempting to use Archi to model activity based costing.

So:

I will be storing prices as properties of elements and relations to properly model ABC. So, if an element has a price of $50 and one of it's relations gets 50% of that, I want the relation to have a property that says it holds $25.

Where the handling comes into play is in live updating this view. So if someone changes the price of the element to $60, the relation should now reflect $30.

Phil Beauvoir

The basic method is to add a model listener somewhere in your model:

IEditorModelManager.INSTANCE.addPropertyChangeListener(this);

and implement propertyChange:

    public void propertyChange(PropertyChangeEvent evt) {
        if(IEditorModelManager.PROPERTY_ECORE_EVENT.equals(evt.getPropertyName())) {
           
            Notification msg = (Notification)evt.getNewValue();
            Object feature = msg.getFeature();
           
            if(feature == IArchimatePackage.Literals.PROPERTY__VALUE) {
                IProperty property = (IProperty)msg.getNotifier();
                String newValue = property.getValue();
                IArchimateModelObject owner = (IArchimateModelObject)property.eContainer();

                // Find other object(s) to change and change them using the model's Command Stack
                String calculatedNewValue = ...;
                IProperty propertyFromOtherElement = ...;

                CommandStack stack = (CommandStack)owner.getArchimateModel().getAdapter(CommandStack.class);
                stack.execute(new EObjectFeatureCommand("Set Property", propertyFromOtherElement,
                        IArchimatePackage.Literals.PROPERTY__VALUE, calculatedNewValue));
            }
        }
    }
If you value and use Archi, please consider making a donation!
Ask your ArchiMate related questions to the ArchiMate Community's Discussion Board.

Whinard

This works perfectly, thank you.
Another quick question, I am struggling to find the method call to find the currently open view, could you help me out?

Thank you!

Phil Beauvoir

Can I ask why you need to access the currently open view? I suspect you may not want to do that.
If you value and use Archi, please consider making a donation!
Ask your ArchiMate related questions to the ArchiMate Community's Discussion Board.

Whinard

When someone turns my plugin on, through a menu toggle button, I want it to run the calculations for the ABC. I want it to calculate whatever view is currently displayed by archimate, because I assume that is the view they want.

Phil Beauvoir

Probably:

IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();

And then page.getEditorReferences()

Iterate through the editor refs...
If you value and use Archi, please consider making a donation!
Ask your ArchiMate related questions to the ArchiMate Community's Discussion Board.

Whinard


tgfranck

#10
Quote from: Phil Beauvoir on July 19, 2017, 16:26:12 PM
                ...

                // Find other object(s) to change and change them using the model's Command Stack
                String calculatedNewValue = ...;
                IProperty propertyFromOtherElement = ...;

                CommandStack stack = (CommandStack)owner.getArchimateModel().getAdapter(CommandStack.class);
                stack.execute(new EObjectFeatureCommand("Set Property", propertyFromOtherElement,
                        IArchimatePackage.Literals.PROPERTY__VALUE, calculatedNewValue));
            }
        }
    }


I do not understand this part of the framework very well, but I think this may also help me with something similar I am attempting. I am looking for a way to update the properties of an object that is thread safe. Do you know whether this method of updating an object is thread safe? And is it also possible to register a new property in a similar manner (in addition to updating existing ones)?

Phil Beauvoir

It depends on how you are doing things. When you say "thread safe" do you mean that there may be a danger of two or more threads updating the properties? This kind of situation could be approached in different ways.
If you value and use Archi, please consider making a donation!
Ask your ArchiMate related questions to the ArchiMate Community's Discussion Board.