views:

290

answers:

1

Hi, I am working on a project that is some kind of a 3d visualization of some simulation. This visualization is a separate eclipse plugin that can be run. The problem is that the gui is imagined as a new eclipse perspective with custom views where at runtime, while the visualization is running, in eclipse views in our own perspective values of attributes of objects that are in the visualization need to be shown to the user, so he can watch them.

How can I achieve that? It should be like some debug mode but a user can switch between objects and check their attributes' values while the visualization is running. Do you have any idea how to achieve that? Is there some way I can send events to eclipse view or something similar?

Thank you

+1  A: 

Yes, absolutely you can have views listen to changes on other objects and update. You can hook into the standard eclipse way of selecting objects if the user selection is relevant (do you want your monitoring views to watch different things depending on what the customer selects in the visualization?). More importantly you can design a model that supports listeners so other objects, such as your views can listen to changes in the visualization model and update them selves.

On listening to changes in the visualization. Your views can hook into any listener interfaces in your visualization's model. Then when they get events they can update what ever properties changed and update their display.

In my case I have a model that represents a list of cards in a deck (not regular playing cards BTW, Magic the Gathering cards). The ModelElement, which is the base class for all my different slots in the deck (e.g. cards, comments etc.) uses java.beans.PropertyChangeSupport to help implement support for listening to property changes ():

public synchronized void addPropertyChangeListener (PropertyChangeListener listener)  {
    if (listener == null) {
        throw new IllegalArgumentException ("Property change listener cannot be null."); //$NON-NLS-1$
    }

    myPropertyChangeDelegate.addPropertyChangeListener (listener);
}


public synchronized void removePropertyChangeListener(PropertyChangeListener listener)  {
    if (listener != null) {
        myPropertyChangeDelegate.removePropertyChangeListener (listener);
    }
}


protected void firePropertyChange(String propertyName, Object oldValue, Object newValue)  {
    if (myPropertyChangeDelegate.hasListeners (propertyName))  {
        myPropertyChangeDelegate.firePropertyChange (propertyName, oldValue, newValue);
    }
}


/** Delegate used to implement property change support. */
private transient PropertyChangeSupport myPropertyChangeDelegate;

That way my views can hookup and listen to the elements in the current deck editor's model. For example here is some code from the outline view's deck element listener (called DeckSlotTreeEditPart) which represents elements in the outline view's tree of cards, comments etc in the current deck:

public class DeckSlotTreeEditPart extends AbstractTreeEditPart implements PropertyChangeListener  {

... other code snipped

public void activate ()  {
    if (!isActive ()) {
        super.activate ();
        getDeckSlot ().addPropertyChangeListener (this);
    }
}


@Override
public void deactivate ()  {
    if (isActive ()) {
        super.deactivate ();
        getDeckSlot ().removePropertyChangeListener (this);
    }
}


public void propertyChange (PropertyChangeEvent evt)  {
    refreshVisuals ();
}


protected DeckSlot getDeckSlot ()  {
    return (DeckSlot)getModel ();
}

In your case you can have your views hook into any listening interfaces on the visualization you want and update them selves as the events from those listeners fire. You can use PropertyChangeSupport or design your own listener interfaces if none exist already.

On listening to selection changes. Here is a snippet of code from one a viewer in one of my apps. This view listens to selection changes in the editor or other selection providers and updates itself to show the properties of the newly selected 'card' object (see eclipse.org help for ISelectionListener):

public class CardInfo extends ViewPart implements ISelectionListener, ICardHistoryDelegate, 
    IPinViewDelegate, IToggleSearchBarDelegate, ICardSearchListener  {

... other methods snipped

public void createPartControl (Composite parent)  {
    ... rest of method that actually creates the view components snipped

    //  Hook up to listen to selection changes
    getSite ().getWorkbenchWindow ().getSelectionService ().addSelectionListener (this);
}

public void selectionChanged (IWorkbenchPart part, ISelection selection)  {

    if (selection.isEmpty()  ||  !(selection instanceof IStructuredSelection))  {
        //  Do not clear the view even for empty selections or selections of another 
        //  type - just do nothing.  That way the last card looked at will be visible no 
        //  matter what else happens
        return;
    }

    //  Display the first selected element
    IStructuredSelection structuredSel = (IStructuredSelection)selection;
    Object firstSelectedObject = structuredSel.getFirstElement ();

    //  Get the ICard interface from the selection - using its IAdaptable interface
    if (firstSelectedObject == null  ||  !(firstSelectedObject instanceof IAdaptable))
        return; // no work to do
    ICard selectedCard = (ICard)((IAdaptable)firstSelectedObject).getAdapter(ICard.class);
    if (selectedCard == null)
        return; // no work to do

... rest of method that actually does something with new selection snipped

My editor uses GEF which provides a selection provider to the eclipse workbench that my views can listen to.

I hope that helps.

Ian

Ian Leslie