Coverage Report - org.argouml.uml.diagram.state.ui.FigCompositeState
 
Classes in this File Line Coverage Branch Coverage Complexity
FigCompositeState
0%
0/129
0%
0/54
2.292
 
 1  
 /* $Id: FigCompositeState.java 17862 2010-01-12 20:06:14Z linus $
 2  
  *****************************************************************************
 3  
  * Copyright (c) 2009 Contributors - see below
 4  
  * All rights reserved. This program and the accompanying materials
 5  
  * are made available under the terms of the Eclipse Public License v1.0
 6  
  * which accompanies this distribution, and is available at
 7  
  * http://www.eclipse.org/legal/epl-v10.html
 8  
  *
 9  
  * Contributors:
 10  
  *    mvw
 11  
  *****************************************************************************
 12  
  *
 13  
  * Some portions of this file was previously release using the BSD License:
 14  
  */
 15  
 
 16  
 // Copyright (c) 1996-2009 The Regents of the University of California. All
 17  
 // Rights Reserved. Permission to use, copy, modify, and distribute this
 18  
 // software and its documentation without fee, and without a written
 19  
 // agreement is hereby granted, provided that the above copyright notice
 20  
 // and this paragraph appear in all copies.  This software program and
 21  
 // documentation are copyrighted by The Regents of the University of
 22  
 // California. The software program and documentation are supplied "AS
 23  
 // IS", without any accompanying services from The Regents. The Regents
 24  
 // does not warrant that the operation of the program will be
 25  
 // uninterrupted or error-free. The end-user understands that the program
 26  
 // was developed for research purposes and is advised not to rely
 27  
 // exclusively on the program for any reason.  IN NO EVENT SHALL THE
 28  
 // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
 29  
 // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
 30  
 // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
 31  
 // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
 32  
 // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY
 33  
 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 34  
 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
 35  
 // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
 36  
 // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
 37  
 // UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 38  
 
 39  
 package org.argouml.uml.diagram.state.ui;
 40  
 
 41  
 import java.awt.Color;
 42  
 import java.awt.Dimension;
 43  
 import java.awt.Rectangle;
 44  
 import java.awt.event.MouseEvent;
 45  
 import java.util.Iterator;
 46  
 import java.util.List;
 47  
 import java.util.TreeMap;
 48  
 import java.util.Vector;
 49  
 
 50  
 import org.argouml.model.Model;
 51  
 import org.argouml.model.RemoveAssociationEvent;
 52  
 import org.argouml.model.UmlChangeEvent;
 53  
 import org.argouml.ui.targetmanager.TargetManager;
 54  
 import org.argouml.uml.diagram.DiagramSettings;
 55  
 import org.argouml.uml.diagram.ui.ActionAddConcurrentRegion;
 56  
 import org.tigris.gef.presentation.Fig;
 57  
 import org.tigris.gef.presentation.FigLine;
 58  
 import org.tigris.gef.presentation.FigRRect;
 59  
 import org.tigris.gef.presentation.FigRect;
 60  
 import org.tigris.gef.presentation.FigText;
 61  
 
 62  
 /**
 63  
  * Class to display graphics for a UML CompositeState in a diagram.
 64  
  *
 65  
  * @author jrobbins@ics.uci.edu
 66  
  */
 67  
 public class FigCompositeState extends FigState {
 68  
 
 69  
     private FigRect cover;
 70  
     private FigLine divider;
 71  
 
 72  
     
 73  
     /**
 74  
      * Construct a new FigStubState.
 75  
      * 
 76  
      * @param owner owning UML element
 77  
      * @param bounds position and size
 78  
      * @param settings rendering settings
 79  
      */
 80  
     public FigCompositeState(Object owner, Rectangle bounds,
 81  
             DiagramSettings settings) {
 82  0
         super(owner, bounds, settings);
 83  0
         initFigs();
 84  0
         updateNameText();
 85  0
     }
 86  
 
 87  
     private void initFigs() {
 88  0
         cover =
 89  
             new FigRRect(getInitialX(), getInitialY(),
 90  
                               getInitialWidth(), getInitialHeight(),
 91  
                               LINE_COLOR, FILL_COLOR);
 92  
 
 93  0
         getBigPort().setLineWidth(0);
 94  
 
 95  0
         divider =
 96  
             new FigLine(getInitialX(),
 97  
                         getInitialY() + 2 + getNameFig().getBounds().height + 1,
 98  
                         getInitialWidth() - 1,
 99  
                         getInitialY() + 2 + getNameFig().getBounds().height + 1,
 100  
                         LINE_COLOR);
 101  
 
 102  
         // add Figs to the FigNode in back-to-front order
 103  0
         addFig(getBigPort());
 104  0
         addFig(cover);
 105  0
         addFig(getNameFig());
 106  0
         addFig(divider);
 107  0
         addFig(getInternal());
 108  
 
 109  0
         setBounds(getBounds());
 110  0
     }
 111  
 
 112  
     /*
 113  
      * @see java.lang.Object#clone()
 114  
      */
 115  
     public Object clone() {
 116  0
         FigCompositeState figClone = (FigCompositeState) super.clone();
 117  0
         Iterator it = figClone.getFigs().iterator();
 118  0
         figClone.setBigPort((FigRRect) it.next());
 119  0
         figClone.cover = (FigRect) it.next();
 120  0
         figClone.setNameFig((FigText) it.next());
 121  0
         figClone.divider = (FigLine) it.next();
 122  0
         figClone.setInternal((FigText) it.next());
 123  0
         return figClone;
 124  
     }
 125  
 
 126  
     ////////////////////////////////////////////////////////////////
 127  
     // accessors
 128  
 
 129  
     /*
 130  
      * @see org.tigris.gef.presentation.Fig#getMinimumSize()
 131  
      */
 132  
     public Dimension getMinimumSize() {
 133  0
         Dimension nameDim = getNameFig().getMinimumSize();
 134  0
         Dimension internalDim = getInternal().getMinimumSize();
 135  
 
 136  0
         int h =
 137  
             SPACE_TOP + nameDim.height
 138  
             + SPACE_MIDDLE + internalDim.height
 139  
             + SPACE_BOTTOM;
 140  0
         int w =
 141  
             Math.max(nameDim.width + 2 * MARGIN,
 142  
                      internalDim.width + 2 * MARGIN);
 143  0
         return new Dimension(w, h);
 144  
     }
 145  
 
 146  
     /*
 147  
      * @see org.tigris.gef.presentation.Fig#getUseTrapRect()
 148  
      */
 149  
     public boolean getUseTrapRect() {
 150  0
         return true;
 151  
     }
 152  
 
 153  
     /*
 154  
      * Override setBounds to keep shapes looking right.
 155  
      *
 156  
      * @see org.tigris.gef.presentation.Fig#setBoundsImpl(int, int, int, int)
 157  
      */
 158  
     protected void setStandardBounds(int x, int y, int w, int h) {
 159  0
         if (getNameFig() == null) {
 160  0
             return;
 161  
         }
 162  
 
 163  0
         Rectangle oldBounds = getBounds();
 164  0
         Dimension nameDim = getNameFig().getMinimumSize();
 165  0
         List regionsList = getEnclosedFigs();
 166  
 
 167  
         /* If it is concurrent and contains concurrent regions,
 168  
         the bottom region has a minimum height*/
 169  0
         if (getOwner() != null) {
 170  0
             if (isConcurrent()
 171  
                     && !regionsList.isEmpty()
 172  
                     && regionsList.get(regionsList.size() - 1)
 173  
                         instanceof FigConcurrentRegion) {
 174  0
                 FigConcurrentRegion f = 
 175  
                     ((FigConcurrentRegion) regionsList.get(
 176  
                             regionsList.size() - 1));
 177  0
                 Rectangle regionBounds = f.getBounds();
 178  0
                 if ((h - oldBounds.height + regionBounds.height)
 179  
                         <= (f.getMinimumSize().height)) {
 180  0
                     h = oldBounds.height;
 181  0
                     y = oldBounds.y;
 182  
                 }
 183  
             }
 184  
         }
 185  
 
 186  0
         getNameFig().setBounds(x + MARGIN,
 187  
                 y + SPACE_TOP,
 188  
                 w - 2 * MARGIN,
 189  
                 nameDim.height);
 190  0
         divider.setShape(x,
 191  
                 y + DIVIDER_Y + nameDim.height,
 192  
                 x + w - 1,
 193  
                 y + DIVIDER_Y + nameDim.height);
 194  
 
 195  0
         getInternal().setBounds(
 196  
                 x + MARGIN,
 197  
                 y + nameDim.height + SPACE_TOP + SPACE_MIDDLE,
 198  
                 w - 2 * MARGIN,
 199  
                 h - nameDim.height - SPACE_TOP - SPACE_MIDDLE - SPACE_BOTTOM);
 200  
 
 201  0
         getBigPort().setBounds(x, y, w, h);
 202  0
         cover.setBounds(x, y, w, h);
 203  
 
 204  0
         calcBounds(); //_x = x; _y = y; _w = w; _h = h;
 205  0
         updateEdges();
 206  0
         firePropChange("bounds", oldBounds, getBounds());
 207  
 
 208  
         /*If it is concurrent and contains concurrent regions,
 209  
         the regions are resized*/
 210  0
         if (getOwner() != null) {
 211  0
             if (isConcurrent()
 212  
                     && !regionsList.isEmpty()
 213  
                     && regionsList.get(regionsList.size() - 1)
 214  
                         instanceof FigConcurrentRegion) {
 215  0
                 FigConcurrentRegion f = ((FigConcurrentRegion) regionsList
 216  
                         .get(regionsList.size() - 1));
 217  0
                 for (int i = 0; i < regionsList.size() - 1; i++) {
 218  0
                     ((FigConcurrentRegion) regionsList.get(i))
 219  
                         .setBounds(x - oldBounds.x, y - oldBounds.y,
 220  
                                 w - 2 * FigConcurrentRegion.INSET_HORZ, true);
 221  
                 }
 222  0
                 f.setBounds(x - oldBounds.x,
 223  
                         y - oldBounds.y, 
 224  
                         w - 2 * FigConcurrentRegion.INSET_HORZ, 
 225  
                         h - oldBounds.height, true);
 226  
             }
 227  
         }
 228  
 
 229  0
     }
 230  
     
 231  
     /*
 232  
      * The returned list of Figs is sorted according layout: from top to bottom.
 233  
      */
 234  
     @Override
 235  
     public Vector<Fig> getEnclosedFigs() {
 236  0
         Vector<Fig> enclosedFigs = super.getEnclosedFigs();
 237  
 
 238  0
         if (isConcurrent()) {
 239  0
             TreeMap<Integer, Fig> figsByY = new TreeMap<Integer, Fig>();
 240  0
             for (Fig fig : enclosedFigs) {
 241  0
                 if (fig instanceof FigConcurrentRegion) {
 242  0
                     figsByY.put(fig.getY(), fig);
 243  
                 }
 244  
             }
 245  0
             return new Vector<Fig>(figsByY.values());
 246  
         }
 247  0
         return enclosedFigs;
 248  
     }
 249  
     
 250  
     /**
 251  
      * @return true if this is a concurrent state, 
 252  
      * false otherwise, or if the owner is not known
 253  
      */
 254  
     public boolean isConcurrent() {
 255  0
         Object owner = getOwner();
 256  0
         if (owner == null) {
 257  0
             return false;
 258  
         }
 259  0
         return Model.getFacade().isConcurrent(owner);
 260  
     }
 261  
 
 262  
     /**
 263  
      * To resize only when a new concurrent region is added,
 264  
      * changing the height.
 265  
      * TODO: Badly named method, it actually sets height. 
 266  
      * @deprecated by mvw in V0.28alpha, 
 267  
      * replaced by better named method.
 268  
      * @param h the new height
 269  
      */
 270  
     @Deprecated
 271  
     public void setBounds(int h) {
 272  0
         setCompositeStateHeight(h);
 273  0
     }
 274  
 
 275  
     /**
 276  
      * To resize only when a new concurrent region is added,
 277  
      * changing the height.
 278  
      * TODO: Probably shouldn't
 279  
      * exist as this class should be listening for added concurrent regions
 280  
      * and call this internally itself.
 281  
      *
 282  
      * @param h the new height
 283  
      */
 284  
     public void setCompositeStateHeight(int h) {
 285  0
         if (getNameFig() == null) {
 286  0
             return;
 287  
         }
 288  0
         Rectangle oldBounds = getBounds();
 289  0
         Dimension nameDim = getNameFig().getMinimumSize();
 290  0
         int x = oldBounds.x;
 291  0
         int y = oldBounds.y;
 292  0
         int w = oldBounds.width;
 293  
 
 294  0
         getInternal().setBounds(
 295  
                 x + MARGIN, 
 296  
                 y + nameDim.height + 4,
 297  
                 w - 2 * MARGIN, 
 298  
                 h - nameDim.height - 6);
 299  0
         getBigPort().setBounds(x, y, w, h);
 300  0
         cover.setBounds(x, y, w, h);
 301  
 
 302  0
         calcBounds(); //_x = x; _y = y; _w = w; _h = h;
 303  0
         updateEdges();
 304  0
         firePropChange("bounds", oldBounds, getBounds());
 305  0
     }
 306  
 
 307  
 
 308  
     /*
 309  
      * @see org.tigris.gef.ui.PopupGenerator#getPopUpActions(java.awt.event.MouseEvent)
 310  
      */
 311  
     public Vector getPopUpActions(MouseEvent me) {
 312  0
         Vector popUpActions = super.getPopUpActions(me);
 313  
         /* Check if multiple items are selected: */
 314  0
         boolean ms = TargetManager.getInstance().getTargets().size() > 1;
 315  0
         if (!ms) {
 316  0
             popUpActions.add(
 317  
                     popUpActions.size() - getPopupAddOffset(),
 318  
                     new ActionAddConcurrentRegion());
 319  
         }
 320  0
         return popUpActions;
 321  
     }
 322  
 
 323  
     /*
 324  
      * @see org.tigris.gef.presentation.Fig#setLineColor(java.awt.Color)
 325  
      */
 326  
     public void setLineColor(Color col) {
 327  0
         cover.setLineColor(col);
 328  0
         divider.setLineColor(col);
 329  0
     }
 330  
 
 331  
     /*
 332  
      * @see org.tigris.gef.presentation.Fig#getLineColor()
 333  
      */
 334  
     public Color getLineColor() {
 335  0
         return cover.getLineColor();
 336  
     }
 337  
 
 338  
     /*
 339  
      * @see org.tigris.gef.presentation.Fig#setFillColor(java.awt.Color)
 340  
      */
 341  
     public void setFillColor(Color col) {
 342  0
         cover.setFillColor(col);
 343  0
     }
 344  
 
 345  
     /*
 346  
      * @see org.tigris.gef.presentation.Fig#getFillColor()
 347  
      */
 348  
     public Color getFillColor() {
 349  0
         return cover.getFillColor();
 350  
     }
 351  
 
 352  
     /*
 353  
      * @see org.tigris.gef.presentation.Fig#setFilled(boolean)
 354  
      */
 355  
     public void setFilled(boolean f) {
 356  0
         cover.setFilled(f);
 357  0
         getBigPort().setFilled(f);
 358  0
     }
 359  
 
 360  
 
 361  
     @Override
 362  
     public boolean isFilled() {
 363  0
         return cover.isFilled();
 364  
     }
 365  
 
 366  
     /*
 367  
      * @see org.tigris.gef.presentation.Fig#setLineWidth(int)
 368  
      */
 369  
     public void setLineWidth(int w) {
 370  0
         cover.setLineWidth(w);
 371  0
         divider.setLineWidth(w);
 372  0
     }
 373  
 
 374  
     /*
 375  
      * @see org.tigris.gef.presentation.Fig#getLineWidth()
 376  
      */
 377  
     public int getLineWidth() {
 378  0
         return cover.getLineWidth();
 379  
     }
 380  
 
 381  
     ////////////////////////////////////////////////////////////////
 382  
     // event processing
 383  
 
 384  
     @Override 
 385  
     protected void updateLayout(UmlChangeEvent event) {
 386  
         /* We only handle the case where a region has been removed: */
 387  0
         if (!(event instanceof RemoveAssociationEvent) || 
 388  
                 !"subvertex".equals(event.getPropertyName())) {
 389  0
             return;
 390  
         }
 391  
         
 392  0
         final Object removedRegion = event.getOldValue();
 393  
         
 394  0
         List<FigConcurrentRegion> regionFigs =
 395  
             ((List<FigConcurrentRegion>) getEnclosedFigs().clone());
 396  
 
 397  0
         int totHeight = getInitialHeight();
 398  0
         if (!regionFigs.isEmpty()) {
 399  0
             Fig removedFig = null;
 400  0
             for (FigConcurrentRegion figRegion : regionFigs) {
 401  0
                 if (figRegion.getOwner() == removedRegion) {
 402  0
                     removedFig = figRegion;
 403  0
                     removeEnclosedFig(figRegion);
 404  0
                     break;
 405  
                 }
 406  
             }
 407  0
             if (removedFig != null) {
 408  0
                 regionFigs.remove(removedFig);
 409  0
                 if (!regionFigs.isEmpty()) {
 410  0
                     for (FigConcurrentRegion figRegion : regionFigs) {
 411  0
                         if (figRegion.getY() > removedFig.getY()) {
 412  0
                             figRegion.displace(0, -removedFig.getHeight());
 413  
                         }
 414  
                     }
 415  0
                     totHeight = getHeight() - removedFig.getHeight();
 416  
                 }
 417  
             }
 418  
         }
 419  
         
 420  0
         setBounds(getX(), getY(), getWidth(), totHeight);
 421  
 
 422  
         // do we need to 
 423  0
         renderingChanged();
 424  0
     }
 425  
 
 426  
 
 427  
     /*
 428  
      * @see org.argouml.uml.diagram.state.ui.FigState#getInitialHeight()
 429  
      */
 430  
     protected int getInitialHeight() {
 431  0
         return 150;
 432  
     }
 433  
 
 434  
     /*
 435  
      * @see org.argouml.uml.diagram.state.ui.FigState#getInitialWidth()
 436  
      */
 437  
     protected int getInitialWidth() {
 438  0
         return 180;
 439  
     }
 440  
 
 441  
     /*
 442  
      * @see org.argouml.uml.diagram.state.ui.FigState#getInitialX()
 443  
      */
 444  
     protected int getInitialX() {
 445  0
         return 0;
 446  
     }
 447  
 
 448  
     /*
 449  
      * @see org.argouml.uml.diagram.state.ui.FigState#getInitialY()
 450  
      */
 451  
     protected int getInitialY() {
 452  0
         return 0;
 453  
     }
 454  
 
 455  
 } /* end class FigCompositeState */