/* * Created on Jul 15, 2004 */ package com.realpersist.gef.part; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Iterator; import java.util.List; import org.eclipse.draw2d.IFigure; import org.eclipse.gef.ConnectionEditPart; import org.eclipse.gef.EditPart; import org.eclipse.gef.GraphicalEditPart; import org.eclipse.gef.editparts.AbstractGraphicalEditPart; import com.realpersist.gef.model.PropertyAwareObject; /** * An abstract EditPart implementation which is property aware and responds to * PropertyChangeEvents fired from the model * @author Phil Zoio */ public abstract class PropertyAwarePart extends AbstractGraphicalEditPart implements PropertyChangeListener { /** * @see org.eclipse.gef.EditPart#activate() */ public void activate() { super.activate(); PropertyAwareObject propertyAwareObject = (PropertyAwareObject) getModel(); propertyAwareObject.addPropertyChangeListener(this); } /** * @see org.eclipse.gef.EditPart#deactivate() */ public void deactivate() { super.deactivate(); PropertyAwareObject propertyAwareObject = (PropertyAwareObject) getModel(); propertyAwareObject.removePropertyChangeListener(this); } /** * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent) */ public void propertyChange(PropertyChangeEvent evt) { String property = evt.getPropertyName(); if (PropertyAwareObject.CHILD.equals(property)) { handleChildChange(evt); } if (PropertyAwareObject.REORDER.equals(property)) { handleReorderChange(evt); } else if (PropertyAwareObject.OUTPUT.equals(property)) { handleOutputChange(evt); } else if (PropertyAwareObject.INPUT.equals(property)) { handleInputChange(evt); } else if (PropertyAwareObject.NAME.equals(property)) { commitNameChange(evt); } else if (PropertyAwareObject.BOUNDS.equals(property)) { handleBoundsChange(evt); } else if (PropertyAwareObject.LAYOUT.equals(property)) { handleLayoutChange(evt); } //we want direct edit name changes to update immediately //not use the Graph animation, if automatic layout is being used if (PropertyAwareObject.NAME.equals(property)) { GraphicalEditPart graphicalEditPart = (GraphicalEditPart) (getViewer().getContents()); IFigure partFigure = graphicalEditPart.getFigure(); partFigure.getUpdateManager().performUpdate(); } } /** * Called when change to one of the inputs occurs */ private void handleInputChange(PropertyChangeEvent evt) { //this works but is not efficient //refreshTargetConnections(); //a more efficient implementation should either remove or add the //relevant target connection //using the removeTargetConnection(ConnectionEditPart connection) or //addTargetConnection(ConnectionEditPart connection, int index) Object newValue = evt.getNewValue(); Object oldValue = evt.getOldValue(); if (!((oldValue != null) ^ (newValue != null))) { throw new IllegalStateException("Exactly one of old or new values must be non-null for INPUT event"); } if (newValue != null) { //add new connection ConnectionEditPart editPart = createOrFindConnection(newValue); int modelIndex = getModelTargetConnections().indexOf(newValue); addTargetConnection(editPart, modelIndex); } else { //remove connection List children = getTargetConnections(); ConnectionEditPart partToRemove = null; for (Iterator iter = children.iterator(); iter.hasNext();) { ConnectionEditPart part = (ConnectionEditPart) iter.next(); if (part.getModel() == oldValue) { partToRemove = part; break; } } if (partToRemove != null) removeTargetConnection(partToRemove); } getContentPane().revalidate(); } /** * Called when change to one of the outputs occurs */ private void handleOutputChange(PropertyChangeEvent evt) { //this works but is not efficient //refreshSourceConnections(); // a more efficient implementation should either remove or add the // relevant target connect //using the removeSourceConnection(ConnectionEditPart connection) or //addSourceConnection(ConnectionEditPart connection, int index) Object newValue = evt.getNewValue(); Object oldValue = evt.getOldValue(); if (!((oldValue != null) ^ (newValue != null))) { throw new IllegalStateException("Exactly one of old or new values must be non-null for INPUT event"); } if (newValue != null) { //add new connection ConnectionEditPart editPart = createOrFindConnection(newValue); int modelIndex = getModelSourceConnections().indexOf(newValue); addSourceConnection(editPart, modelIndex); } else { //remove connection List children = getSourceConnections(); ConnectionEditPart partToRemove = null; for (Iterator iter = children.iterator(); iter.hasNext();) { ConnectionEditPart part = (ConnectionEditPart) iter.next(); if (part.getModel() == oldValue) { partToRemove = part; break; } } if (partToRemove != null) removeSourceConnection(partToRemove); } getContentPane().revalidate(); } /** * called when child added or removed */ protected void handleChildChange(PropertyChangeEvent evt) { //we could do this but it is not very efficient //refreshChildren(); Object newValue = evt.getNewValue(); Object oldValue = evt.getOldValue(); if (!((oldValue != null) ^ (newValue != null))) { throw new IllegalStateException("Exactly one of old or new values must be non-null for CHILD event"); } if (newValue != null) { //add new child EditPart editPart = createChild(newValue); int modelIndex = getModelChildren().indexOf(newValue); addChild(editPart, modelIndex); } else { List children = getChildren(); EditPart partToRemove = null; for (Iterator iter = children.iterator(); iter.hasNext();) { EditPart part = (EditPart) iter.next(); if (part.getModel() == oldValue) { partToRemove = part; break; } } if (partToRemove != null) removeChild(partToRemove); } //getContentPane().revalidate(); } /** * Called when columns are re-ordered within */ protected void handleReorderChange(PropertyChangeEvent evt) { refreshChildren(); refreshVisuals(); } /** * @param subclass * decides what to do if layout property event is fired */ protected void handleLayoutChange(PropertyChangeEvent evt) { } /** * handles change in bounds, to be overridden by subclass */ protected void handleBoundsChange(PropertyChangeEvent evt) { } /** * Handles change in name - to be overridden by subclasses */ protected void commitNameChange(PropertyChangeEvent evt) { } }