Author: bobtarling Date: 2008-10-28 15:52:30-0700 New Revision: 15948 Modified: branches/BRANCH_0_26_x/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigClassifierBoxWithAttributes.java branches/BRANCH_0_26_x/src/argouml-app/src/org/argouml/uml/diagram/ui/FigNodeModelElement.java
Log: Issue 5438: Wrap invalid element exception and use minal listener update facility Modified: branches/BRANCH_0_26_x/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigClassifierBoxWithAttributes.java Url: http://argouml.tigris.org/source/browse/argouml/branches/BRANCH_0_26_x/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigClassifierBoxWithAttributes.java?view=diff&rev=15948&p1=branches/BRANCH_0_26_x/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigClassifierBoxWithAttributes.java&p2=branches/BRANCH_0_26_x/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigClassifierBoxWithAttributes.java&r1=15947&r2=15948 ============================================================================== --- branches/BRANCH_0_26_x/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigClassifierBoxWithAttributes.java (original) +++ branches/BRANCH_0_26_x/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigClassifierBoxWithAttributes.java 2008-10-28 15:52:30-0700 @@ -29,7 +29,9 @@ import java.awt.Rectangle; import java.util.ArrayList; import java.util.Collection; +import java.util.HashSet; import java.util.Iterator; +import java.util.Set; import javax.swing.Action; @@ -104,32 +106,49 @@ + "attributesVisible=" + isAttributesVisible() + ";"; } + @Override protected void updateListeners(Object oldOwner, Object newOwner) { - if (oldOwner != null) { - removeAllElementListeners(); - } + Set<Object[]> listeners = new HashSet<Object[]>(); + + // Collect the set of model elements that we want to listen to if (newOwner != null) { + // TODO: Because we get called on each and every change event, when + // the model is in a state of flux, we'll often get an + // InvalidElementException before we finish this collection. The + // only saving grace is that we're called SO many times that on the + // last time, things should be stable again and we'll get a good set + // of elements for the final update. We need a better mechanism. + // add the listeners to the newOwner - addElementListener(newOwner); + listeners.add(new Object[] {newOwner, null}); + // and its stereotypes // TODO: Aren't stereotypes handled elsewhere? - Collection c = new ArrayList( - Model.getFacade().getStereotypes(newOwner)); + for (Object stereotype + : Model.getFacade().getStereotypes(newOwner)) { + listeners.add(new Object[] {stereotype, null}); + } + // and its features for (Object feat : Model.getFacade().getFeatures(newOwner)) { - c.add(feat); + listeners.add(new Object[] {feat, null}); // and the stereotypes of its features - c.addAll(new ArrayList(Model.getFacade().getStereotypes(feat))); + for (Object stereotype + : Model.getFacade().getStereotypes(feat)) { + listeners.add(new Object[] {stereotype, null}); + } // and the parameter of its operations if (Model.getFacade().isAOperation(feat)) { - c.addAll(Model.getFacade().getParameters(feat)); + for (Object param : Model.getFacade().getParameters(feat)) { + listeners.add(new Object[] {param, null}); + } } } - // And now add listeners to them all: - for (Object obj : c) { - addElementListener(obj); - } } + + // Update the listeners to match the desired set using the minimal + // update facility + updateElementListeners(listeners); } public void renderingChanged() { Modified: branches/BRANCH_0_26_x/src/argouml-app/src/org/argouml/uml/diagram/ui/FigNodeModelElement.java Url: http://argouml.tigris.org/source/browse/argouml/branches/BRANCH_0_26_x/src/argouml-app/src/org/argouml/uml/diagram/ui/FigNodeModelElement.java?view=diff&rev=15948&p1=branches/BRANCH_0_26_x/src/argouml-app/src/org/argouml/uml/diagram/ui/FigNodeModelElement.java&p2=branches/BRANCH_0_26_x/src/argouml-app/src/org/argouml/uml/diagram/ui/FigNodeModelElement.java&r1=15947&r2=15948 ============================================================================== --- branches/BRANCH_0_26_x/src/argouml-app/src/org/argouml/uml/diagram/ui/FigNodeModelElement.java (original) +++ branches/BRANCH_0_26_x/src/argouml-app/src/org/argouml/uml/diagram/ui/FigNodeModelElement.java 2008-10-28 15:52:30-0700 @@ -42,8 +42,10 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Set; import java.util.Vector; import javax.swing.Action; @@ -2108,6 +2110,59 @@ } listeners.clear(); } + + private void removeElementListeners(Set<Object[]> listenerSet) { + for (Object[] listener : listenerSet) { + Object property = listener[1]; + if (property == null) { + Model.getPump().removeModelEventListener(this, listener[0]); + } else if (property instanceof String[]) { + Model.getPump().removeModelEventListener(this, listener[0], + (String[]) property); + } else if (property instanceof String) { + Model.getPump().removeModelEventListener(this, listener[0], + (String) property); + } else { + throw new RuntimeException( + "Internal error in removeAllElementListeners"); + } + } + listeners.removeAll(listenerSet); + } + + private void addElementListeners(Set<Object[]> listenerSet) { + for (Object[] listener : listenerSet) { + Object property = listener[1]; + if (property == null) { + addElementListener(listener[0]); + } else if (property instanceof String[]) { + addElementListener(listener[0], (String[]) property); + } else if (property instanceof String) { + addElementListener(listener[0], (String) property); + } else { + throw new RuntimeException( + "Internal error in addElementListeners"); + } + } + } + + /** + * Update the set of registered listeners to match the given set using + * a minimal update strategy to remove unneeded listeners and add new + * listeners. + * + * @param listenerSet a set of arrays containing a tuple of a UML element + * to be listened to and a set of property to be listened for. + */ + protected void updateElementListeners(Set<Object[]> listenerSet) { + Set<Object[]> removes = new HashSet<Object[]>(listeners); + removes.removeAll(listenerSet); + removeElementListeners(removes); + + Set<Object[]> adds = new HashSet<Object[]>(listenerSet); + adds.removeAll(listeners); + addElementListeners(adds); + } protected HashMap<String, Object> getNotationArguments() { return npArguments; --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
