Poseidon's Target API

Motivation

Let's say your plug-in wants to set special tagged values (TVs) to Interfaces, and you want to do it via a GUI. It is not a good idea to have the user type in the name and value for a tagged value as it is clumsy, error-prone, and the user has to know the name of the TV. So you need a panel somewhere that shows the current values of the currently selected element, and whenever a setting in your panel is changed, the value should be stored with the same element.
What is a target?
We call the currently selected element the Target. A target has three parts: element, diagram element, and diagram.

Remember that there is a difference between a model element and its graphical representation. A Class, for example, may be in the project only once, but it shows up in several diagrams where it is displayed in different contexts. So there is a 1-to-n relation between elements and graphical representations.

An element is the UML element. It exists once in the whole project. A di element, short for 'diagram element', is a graphical representation of the UML element. There may be none, one, or several di elements for one element. And a diagram is the third part of the target. As the user may multi-select, several elements (di elements/diagrams) may be selected. Whenever the user selects anything with the mouse, it can be represented as a triple of elements, di elements, and diagrams, some of which may be empty lists.

Another part of the Target is the visible diagram. Currently, one diagram is always visible in the workspace. This is the visible diagram, not to be confused with the targeted diagram(s). The visible diagram is always exactly one, wheras the targeted diagram(s) may be none, one, or several.

Example

If the user selects a class in the tree, and a diagram is visible where the class can also be found, the resulting target will hold the chosen element, and the corresponding di element(s), and no diagram. Visually, the element will be selected in the tree, and the di element will have the yellow handles at the corners.

If the user selects an element in the tree for which there is no di element in the visible diagram, the target will hold the element and nothing else.
If the user clicks on an empty area in a diagram, or selects a diagram in the tree, the target will hold the diagram and nothing else.


Implementing a TargetListener

Typically, your plug-in's panel will be a tab in the Details Pane and be visible as another tab in the area below the diagrams. Add your component via PoseidonUIConnector.addDetailsTab(Class projectClass, XTab newTab). To actually get hold of the current target, your component will have to register with the com.gentleware.jboogie.kernel.TargetManager as com.gentleware.jboogie.kernel.TargetManager.Listener. Implement the single method void handleTargetChanged(Target oldTarget, Target newTarget). Call TargetManager.addListener(myClass) in the installation part of your plug-in.

It's not sufficient to add only a target listener with PoseidonUIConnector.addTargetListener(TargetListener listener) when installing the plug-in. Because the target manager is project dependent, any time the project is changed a new target manager is created. So, you have to listen to project changes. After a project is created or loaded you have to add a target listener again.

Example

public void installed() {
   ...
   PoseidonProject.addProjectListener(_projectListener);
   ...
}

private TargetListener _targetListener = new TargetListener() {
    public void handleTargetChanged(Target oldTarget, Target newTarget)
      {
      ...

    }
  };

private VetoableChangeListener _projectListener = new
  VetoableChangeListener() {
      public void vetoableChange(final PropertyChangeEvent evt) {
        final String eventName = evt.getPropertyName();
        if(PoseidonProject.PROPERTY_EVENT_CREATED.equals(eventName) ||
         PoseidonProject.PROPERTY_EVENT_LOADED.equals(eventName)) {
           PoseidonUIConnector.addTargetListener(_targetListener);
        }
      }
  };

Please do not forget to call TargetManager.removeListener(myClass) in your plug-in's uninstall routine.


Processing the Target

In handleTargetChanged, you can inspect the com.gentleware.jboogie.kernel.Target object that is given. Each Target class has the methods:

public org.omg.uml.diagraminterchange.Diagram getTargetedDiagram()
public Object getElement()
public org.omg.uml.diagraminterchange.DiagramElement getDiElement()

public org.omg.uml.diagraminterchange.Diagram getVisibleDiagram()

public List getTargetedDiagrams()
public List getElements()
public List getDiElements()

Now, test the element in the target if it is not null and an instance of the desired class. Then, display the element's values in your component. Whenever necessary, set the element's values in the event handlers of your UI elements.

Example

import com.gentleware.jboogie.kernel.TargetManager;
import com.gentleware.jboogie.kernel.Target;
import org.omg.uml.diagraminterchange.Diagram;
import org.omg.uml.diagraminterchange.DiagramElement;
public class MyClass implements TargetManager.Listener {
public void handleTargetChanged(Target oldTarget, Target newTarget){
Diagram visibleDiagram = newTarget.getVisibleDiagram();
DiagramElement diElement = newTarget.getDiagramElement();
Object element = newTarget.getElement();
if (element!=null && element instanceof Actor) {
System.out.println("Actor selected!");
}
}
}
TargetManager.addListener(new MyClass());



Contact Us

Any questions or suggestions?

Send us a note at plugins@gentleware.com or post to the 'Plug-Ins' section of our forum.



© 2000 - 2010 Gentleware AG
         
                        
 support  documentation  documentation  APIs