001 /* 002 Copyright (C) 2002 Renaud Pawlak <renaud@aopsys.com> 003 004 This program is free software; you can redistribute it and/or modify 005 it under the terms of the GNU Lesser General Public License as 006 published by the Free Software Foundation; either version 2 of the 007 License, or (at your option) any later version. 008 009 This program is distributed in the hope that it will be useful, 010 but WITHOUT ANY WARRANTY; without even the implied warranty of 011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 GNU Lesser General Public License for more details. 013 014 You should have received a copy of the GNU Lesser General Public 015 License along with this program; if not, write to the Free Software 016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 017 USA. */ 018 019 package org.objectweb.jac.ide.diagrams; 020 021 import CH.ifa.draw.figures.LineConnection; 022 import CH.ifa.draw.figures.PolyLineFigure; 023 import CH.ifa.draw.figures.PolyLineHandle; 024 import CH.ifa.draw.framework.Drawing; 025 import CH.ifa.draw.framework.DrawingView; 026 import CH.ifa.draw.framework.Figure; 027 import CH.ifa.draw.framework.Locator; 028 import CH.ifa.draw.standard.NullHandle; 029 import org.objectweb.jac.aspects.gui.ObjectUpdate; 030 import org.objectweb.jac.core.rtti.FieldItem; 031 import org.objectweb.jac.ide.Link; 032 import org.objectweb.jac.ide.RelationLink; 033 import org.objectweb.jac.ide.RelationRole; 034 import org.objectweb.jac.ide.Role; 035 import org.objectweb.jac.util.Log; 036 import java.awt.Point; 037 import java.util.Iterator; 038 import java.util.List; 039 import java.util.Vector; 040 import org.objectweb.jac.aspects.gui.Utils; 041 042 public class LinkFigure extends LineConnection 043 implements ObjectUpdate, ModelElementFigure 044 { 045 046 public final static int NAME = AttachedTextFigure.NAME; 047 public final static int START_CARDINALITY = AttachedTextFigure.START_CARDINALITY; 048 public final static int END_CARDINALITY = AttachedTextFigure.END_CARDINALITY; 049 public final static int START_ROLE = AttachedTextFigure.START_ROLE; 050 public final static int END_ROLE = AttachedTextFigure.END_ROLE; 051 052 List attachedFigures = new Vector(); 053 054 org.objectweb.jac.ide.LinkFigure linkFig; 055 056 org.objectweb.jac.ide.LinkFigure getLinkFigure() { 057 return linkFig; 058 } 059 060 public LinkFigure(org.objectweb.jac.ide.LinkFigure figure) { 061 setLinkFigure(figure); 062 setDecorations(); 063 layout(); 064 } 065 066 public LinkFigure() { 067 setDecorations(); 068 } 069 070 /** 071 * Set the decorations at both end of the link 072 */ 073 void setDecorations() { 074 setStartDecoration(null); 075 setEndDecoration(null); 076 } 077 078 protected void layout() { 079 080 } 081 082 public void addAttachedTextFigure(AttachedTextFigure f) { 083 attachedFigures.add(f); 084 } 085 086 public AttachedTextFigure createAttachedFigure(int type) { 087 AttachedTextFigure at = new AttachedTextFigure(linkFig,type); 088 at.connect(this); 089 at.refresh(); 090 return at; 091 } 092 093 public AttachedTextFigure createAttachedFigure(int type,String s) { 094 AttachedTextFigure at = new AttachedTextFigure(linkFig,type); 095 at.setText(s); 096 at.connect(this); 097 return at; 098 } 099 100 public AttachedTextFigure createName() { 101 return createAttachedFigure(NAME); 102 } 103 104 public AttachedTextFigure createEndRole() { 105 return createAttachedFigure(END_ROLE); 106 } 107 108 public AttachedTextFigure createStartRole() { 109 return createAttachedFigure(START_ROLE); 110 } 111 112 public AttachedTextFigure createStartCardinality() { 113 return createAttachedFigure(START_CARDINALITY); 114 } 115 116 public AttachedTextFigure createEndCardinality() { 117 return createAttachedFigure(END_CARDINALITY); 118 } 119 120 121 public AttachedTextFigure createName(String s) { 122 return createAttachedFigure(NAME,s); 123 } 124 125 public AttachedTextFigure createEndRole(String s) { 126 return createAttachedFigure(END_ROLE,s); 127 } 128 129 public AttachedTextFigure createStartRole(String s) { 130 return createAttachedFigure(START_ROLE,s); 131 } 132 133 public AttachedTextFigure createStartCardinality(String s) { 134 return createAttachedFigure(START_CARDINALITY,s); 135 } 136 137 public AttachedTextFigure createEndCardinality(String s) { 138 return createAttachedFigure(END_CARDINALITY,s); 139 } 140 141 Link substance; 142 143 // View interface 144 public void setFocus(FieldItem field, Object extraOption) {} 145 146 public void objectUpdated(Object object, Object extra) { 147 if (DiagramView.init) 148 return; 149 Log.trace("figures.link","objectUpdated("+object+")"); 150 DiagramView.init = true; 151 Link link = null; 152 if (object instanceof Link) { 153 link = (Link)object; 154 } else if (object instanceof Role) { 155 link = linkFig.getLink(); 156 } else { 157 link = ((org.objectweb.jac.ide.LinkFigure)object).getLink(); 158 } 159 160 try { 161 if (link instanceof RelationLink) { 162 RelationLink roledLink = (RelationLink)link; 163 Iterator it = attachedFigures.iterator(); 164 while (it.hasNext()) { 165 AttachedTextFigure cur = (AttachedTextFigure)it.next(); 166 cur.refresh(); 167 } 168 } 169 170 setDecorations(); 171 changed(); 172 /* 173 if (substance.getEnd() != ((ModelElementFigure)endFigure()).getSubstance()) { 174 Figure newEnd = ((DiagramView)DiagramView.diagramViews.get(0)) 175 .findElement((ModelElement)substance.getEnd()); 176 if( newEnd != null ) { 177 Log.trace("figures","reconnecting relation to "+newEnd); 178 disconnectEnd(); 179 endPoint(newEnd.center().x,newEnd.center().y); 180 connectEnd(newEnd.connectorAt( 181 newEnd.center().x,newEnd.center().y)); 182 updateConnection(); 183 } else { 184 ((DiagramView)DiagramView.diagramViews.get(0)).view().drawing().remove(this); 185 } 186 } 187 if(DiagramView.diagramViews.size()>0) { 188 ((DiagramView)DiagramView.diagramViews.get(0)).view() 189 .paint(((DiagramView)DiagramView.diagramViews.get(0)) 190 .view().getGraphics()); 191 } 192 */ 193 } finally { 194 DiagramView.init = false; 195 } 196 } 197 198 public void insertPointAt(Point p, int i) { 199 super.insertPointAt(p, i); 200 if(!DiagramView.init) 201 linkFig.addPoint(i,p); 202 } 203 204 public void removePointAt(int i) { 205 super.removePointAt(i); 206 if(!DiagramView.init) 207 linkFig.removePoint(i); 208 } 209 210 public void close() { 211 Link link = linkFig.getLink(); 212 Utils.unregisterObject(link,this); 213 if (link instanceof RelationLink) { 214 RelationLink rel = (RelationLink)link; 215 Utils.unregisterObject(rel.getStartRole(),this); 216 Utils.unregisterObject(rel.getEndRole(),this); 217 } 218 } 219 220 /** 221 * Get the value of substance. 222 * @return value of substance. 223 */ 224 public org.objectweb.jac.ide.ModelElement getSubstance() { 225 return linkFig.getLink(); 226 } 227 228 public void setLinkFigure(org.objectweb.jac.ide.LinkFigure linkFig) { 229 Link link; 230 if (this.linkFig!=null) { 231 link = this.linkFig.getLink(); 232 Utils.unregisterObject(link,this); 233 if (link instanceof RelationLink) { 234 RelationLink rel = (RelationLink)link; 235 Utils.unregisterObject(rel.getStartRole(),this); 236 Utils.unregisterObject(rel.getEndRole(),this); 237 } 238 } 239 this.linkFig = linkFig; 240 link = linkFig.getLink(); 241 Utils.registerObject(link,this); 242 if (link instanceof RelationLink) { 243 RelationLink rel = (RelationLink)link; 244 Utils.registerObject(rel.getStartRole(),this); 245 Utils.registerObject(rel.getEndRole(),this); 246 } 247 setDecorations(); 248 } 249 250 public void handleConnect(Figure start, ModelElementFigure end) { 251 if( substance == null ) return; 252 if( end.getSubstance() != substance.getEnd() ) { 253 DiagramView.init = true; 254 substance.setEnd(end.getSubstance()); 255 DiagramView.init = false; 256 } 257 } 258 259 public void handleDisconnect(Figure start, Figure end) { 260 } 261 262 public Vector handles() { 263 264 Vector handles = new Vector(fPoints.size()); 265 for (int i = 0; i < fPoints.size(); i++) { 266 handles.addElement(new LinkHandle(this, locator(i), i)); 267 } 268 // don't allow to reconnect the starting figure 269 handles.setElementAt(new NullHandle(this, PolyLineFigure.locator(0)), 0); 270 return handles; 271 } 272 273 AttachedTextLocator locator=new AttachedTextLocator(); 274 275 public Locator connectedTextLocator(Figure f) { 276 return locator; 277 } 278 279 protected void basicMoveBy(int dx, int dy) { 280 Log.trace("figures.link","link figure moved "+dx+","+dy); 281 for(int i=1;i<linkFig.getPointCount()-1;i++) { 282 linkFig.setPoint(i,pointAt(i)); 283 } 284 super.basicMoveBy(dx,dy); 285 Log.trace("figures.link","Moved done"); 286 } 287 288 /** 289 * Changes the coordinates of a point of the line connection 290 * @param p the new point 291 * @param i index of the point to modify 292 */ 293 public void setPointAt(Point p, int i) { 294 super.setPointAt(p,i); 295 linkFig.setPoint(i,p); 296 } 297 298 299 /** 300 * Updates the connection. 301 */ 302 public void updateConnection() { 303 if (getStartConnector() != null && getEndConnector() != null) { 304 Point start = getStartConnector().findStart(this); 305 306 if (start != null) { 307 startPoint(start.x, start.y); 308 } 309 310 Point end = getEndConnector().findEnd(this); 311 312 if (end != null) { 313 endPoint(end.x, end.y); 314 } 315 } 316 } 317 318 /** 319 * Initialize associated text figures (cardinality, role name, ...) 320 * @param drawing a drawing to add the figures to 321 */ 322 public void load(Drawing drawing) { 323 Log.trace("diagram",2,"load link "+this); 324 DiagramView.init = true; 325 try { 326 Iterator points = linkFig.getPoints().iterator(); 327 int i = 1; 328 if (points.hasNext()) { 329 points.next(); 330 while (points.hasNext()) { 331 Point p = (Point)points.next(); 332 if (points.hasNext()) 333 insertPointAt(p,i++); 334 } 335 } 336 Link subst = (Link)getSubstance(); 337 Point p; 338 if (subst instanceof RelationLink) { 339 RelationLink lnk = (RelationLink)subst; 340 RelationRole start = lnk.startRole(); 341 RelationRole end = lnk.endRole(); 342 AttachedTextFigure text = createName(); 343 drawing.add(text); 344 p = connectedTextLocator(text).locate(this,text); 345 text.moveBy((int)(linkFig.getNameCorner().getX() 346 - p.getX()+text.size().getWidth()/2), 347 (int)(linkFig.getNameCorner().getY() 348 - p.getY()+text.size().getHeight()/2)); 349 350 text = createStartRole(); 351 drawing.add(text); 352 p = connectedTextLocator(text).locate(this,text); 353 text.moveBy((int)(linkFig.getStartRoleCorner().getX() 354 - p.getX()+text.size().getWidth()/2), 355 (int)(linkFig.getStartRoleCorner().getY() 356 - p.getY()+text.size().getHeight()/2)); 357 358 text = createEndRole(); 359 drawing.add(text); 360 p = connectedTextLocator(text).locate(this,text); 361 text.moveBy((int)(linkFig.getEndRoleCorner().getX() 362 - p.getX()+text.size().getWidth()/2), 363 (int)(linkFig.getEndRoleCorner().getY() 364 - p.getY()+text.size().getHeight()/2)); 365 366 text = createStartCardinality(); 367 drawing.add(text); 368 p = connectedTextLocator(text).locate(this,text); 369 text.moveBy((int)(linkFig.getStartCardinalityCorner().getX() 370 - p.getX()+text.size().getWidth()/2), 371 (int)(linkFig.getStartCardinalityCorner().getY() 372 - p.getY()+text.size().getHeight()/2)); 373 374 text = createEndCardinality(); 375 drawing.add(text); 376 p = connectedTextLocator(text).locate(this,text); 377 text.moveBy((int)(linkFig.getEndCardinalityCorner().getX() 378 - p.getX()+text.size().getWidth()/2), 379 (int)(linkFig.getEndCardinalityCorner().getY() 380 - p.getY()+text.size().getHeight()/2)); 381 } 382 } finally { 383 DiagramView.init=false; 384 } 385 } 386 387 public void release() { 388 super.release(); 389 close(); 390 if(linkFig!=null && linkFig.getDiagram()!=null) { 391 linkFig.getDiagram().removeFigure(linkFig); 392 } 393 } 394 395 // Helper methods 396 public void endPoint(Point p) { 397 endPoint(p.x,p.y); 398 } 399 public void startPoint(Point p) { 400 startPoint(p.x,p.y); 401 } 402 } 403 404 class LinkHandle extends PolyLineHandle { 405 public LinkHandle(PolyLineFigure owner, Locator l, int index) { 406 super(owner, l,index); 407 } 408 409 public void invokeStep(int x, int y, int anchorX, 410 int anchorY, DrawingView view) { 411 super.invokeStep(x,y,anchorX,anchorY,view); 412 } 413 414 }