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 */ 018 019 package org.objectweb.jac.ide.diagrams; 020 021 import CH.ifa.draw.figures.TextFigure; 022 import CH.ifa.draw.framework.Connector; 023 import CH.ifa.draw.framework.DrawingView; 024 import CH.ifa.draw.framework.Figure; 025 import CH.ifa.draw.framework.FigureChangeEvent; 026 import CH.ifa.draw.framework.FigureEnumeration; 027 import CH.ifa.draw.standard.CompositeFigure; 028 import CH.ifa.draw.standard.NullHandle; 029 import CH.ifa.draw.standard.RelativeLocator; 030 import org.objectweb.jac.aspects.gui.ObjectUpdate; 031 import org.objectweb.jac.aspects.gui.Utils; 032 import org.objectweb.jac.core.Wrappee; 033 import org.objectweb.jac.core.Wrapping; 034 import org.objectweb.jac.ide.Class; 035 import org.objectweb.jac.ide.Field; 036 import org.objectweb.jac.ide.Method; 037 import org.objectweb.jac.ide.ModelElement; 038 import org.objectweb.jac.ide.Package; 039 import org.objectweb.jac.ide.Projects; 040 import org.objectweb.jac.util.Log; 041 import java.awt.Color; 042 import java.awt.Dimension; 043 import java.awt.Graphics; 044 import java.awt.Point; 045 import java.awt.Rectangle; 046 import java.util.Iterator; 047 import java.util.Vector; 048 049 public class ClassFigure extends CompositeFigure 050 implements ObjectUpdate, ModelElementFigure 051 { 052 053 private static final int BORDER = 3; 054 // private Rectangle fDisplayBox; 055 056 Vector relationLinkFigures = new Vector(); 057 Vector inheritanceLinkFigures = new Vector(); 058 Vector fieldFigures = new Vector(); 059 Vector methodFigures = new Vector(); 060 061 DrawingView view; 062 063 org.objectweb.jac.ide.ClassFigure classFig; 064 Dimension dimension = new Dimension(); 065 066 public ClassFigure(org.objectweb.jac.ide.ClassFigure figure, Package pack, 067 DrawingView view) { 068 initialize(); 069 this.classFig = figure; 070 this.containerPackage = pack; 071 this.view = view; 072 073 ClassNameFigure name=new ClassNameFigure(figure.getCl(),this); 074 name.setZValue(1); 075 add(name); 076 077 DiagramView.init = true; 078 try { 079 initFields(); 080 initMethods(); 081 } finally { 082 DiagramView.init = false; 083 } 084 Utils.registerObject(classFig.getCl(),this); 085 Utils.registerObject(classFig,this); 086 087 layout(); 088 } 089 090 // ObjectUpdate interface 091 public void objectUpdated(Object object, Object extra) { 092 Vector fs = new Vector(); 093 fs.add(this); 094 initClass(); 095 layout(); 096 changed(); 097 //editor().validate(); 098 // view.draw(view.getGraphics(),new FigureEnumerator(fs)); 099 } 100 101 public void close() { 102 // we should unregister from all objectUpdate events 103 Utils.unregisterObject(classFig.getCl(),this); 104 Utils.unregisterObject(classFig,this); 105 } 106 107 //Serialization support. 108 private static final long serialVersionUID = -7877776240236946511L; 109 private int pertFigureSerializedDataVersion = 1; 110 111 112 boolean isInternal() { 113 return containerPackage.getClasses().contains(classFig.getCl()); 114 } 115 116 Package containerPackage; 117 118 /** 119 * Get the value of containerPackage. 120 * @return value of containerPackage. 121 */ 122 public Package getContainerPackage() { 123 return containerPackage; 124 } 125 126 /** 127 * Set the value of containerPackage. 128 * @param v Value to assign to containerPackage. 129 */ 130 public void setContainerPackage(Package v) { 131 this.containerPackage = v; 132 } 133 134 void initClass() { 135 if (classFig.getCl() == null) { 136 Log.warning("UNRESOLVED CLASS!"); 137 } else { 138 Log.trace("figures","init class "+classFig.getCl().getName()); 139 DiagramView.init = true; 140 try { 141 removeAllMembers(); 142 initTitle(); 143 initFields(); 144 initMethods(); 145 } finally { 146 DiagramView.init = false; 147 } 148 /* 149 Wrapping.invokeRoleMethod((Wrappee)classFig.getCl(),"registerObject", 150 new Object[]{this,null}); 151 Wrapping.invokeRoleMethod((Wrappee)classFig,"registerObject", 152 new Object[]{this,null}); 153 */ 154 } 155 } 156 157 void initTitle() { 158 ClassNameFigure nf = (ClassNameFigure)figures().nextFigure(); 159 nf.setSubstance(classFig.getCl()); 160 nf.setText(classFig.getCl().getName()); 161 } 162 163 164 void initFields() { 165 if (!classFig.isHideFields()) { 166 Iterator it = classFig.getCl().getFields().iterator(); 167 while(it.hasNext()) { 168 Field field = (Field)it.next(); 169 FieldFigure fieldFigure = new FieldFigure(field,this); 170 Log.trace("figures","adding field "+field); 171 fieldFigures.add(fieldFigure); 172 add(fieldFigure); 173 } 174 } 175 } 176 177 void initMethods() { 178 if (!classFig.isHideMethods()) { 179 Iterator it = classFig.getCl().getAllMethods().iterator(); 180 while(it.hasNext()) { 181 Method method = (Method)it.next(); 182 MethodFigure methodFigure = new MethodFigure(method,this); 183 Log.trace("figures","adding method "+method); 184 add(methodFigure); 185 methodFigures.add(methodFigure); 186 } 187 } 188 } 189 190 void removeAllMembers() { 191 FigureEnumeration it = figures(); 192 // skip the title 193 it.nextFigure(); 194 while (it.hasMoreElements()) { 195 Figure f = it.nextFigure(); 196 Log.trace("figures","removing "+f); 197 remove(f); 198 Wrapping.invokeRoleMethod( (Wrappee) ((ModelElementFigure)f).getSubstance(), 199 "unregisterObject",new Object[]{this}); 200 } 201 methodFigures.clear(); 202 fieldFigures.clear(); 203 } 204 205 protected void basicMoveBy(int dx, int dy) { 206 Log.trace("figures",2,this+".basicMoveBy "+dx+","+dy); 207 classFig.translate(dx, dy); 208 super.basicMoveBy(dx, dy); 209 } 210 211 public Rectangle displayBox() { 212 return new Rectangle(classFig.getCorner(),dimension); 213 } 214 215 public void basicDisplayBox(Point origin, Point corner) { 216 classFig.setCorner(origin); 217 dimension.width = corner.x-origin.x; 218 dimension.height = corner.y-origin.y; 219 layout(); 220 } 221 222 protected Color getFillColor() { 223 if (isInternal()) 224 return Color.white; 225 else 226 return Color.lightGray; 227 } 228 229 static final Color VERY_LIGHT_GRAY = new Color(220,220,220); 230 231 protected Color getColor() { 232 if (classFig.getCl().getContainer()!=null) 233 return Color.black; 234 else 235 return VERY_LIGHT_GRAY; 236 } 237 238 protected void drawBorder(Graphics g) { 239 Rectangle r = displayBox(); 240 241 g.setColor(getFillColor()); 242 g.fillRect(r.x, r.y, r.width, r.height); 243 244 g.setColor(getColor()); 245 g.drawRect(r.x, r.y, r.width, r.height); 246 247 Figure f = figureAt(0); 248 Rectangle rf = f.displayBox(); 249 250 g.drawLine(r.x,r.y+rf.height+1,r.x+r.width,r.y+rf.height+1); 251 252 if( fieldFigures.size() > 0 ) { 253 f = (Figure) fieldFigures.get(0); 254 rf = f.displayBox(); 255 g.drawLine(r.x,rf.y,r.x+r.width,rf.y); 256 } 257 } 258 259 public void draw(Graphics g) { 260 Log.trace("diagram.draw",this+".draw"); 261 drawBorder(g); 262 super.draw(g); 263 } 264 265 public Vector handles() { 266 Vector handles = new Vector(); 267 handles.addElement(new NullHandle(this, RelativeLocator.northWest())); 268 handles.addElement(new NullHandle(this, RelativeLocator.northEast())); 269 handles.addElement(new NullHandle(this, RelativeLocator.southWest())); 270 handles.addElement(new NullHandle(this, RelativeLocator.southEast())); 271 return handles; 272 } 273 274 void addRelationLinkFigure(RelationLinkFigure a) { 275 relationLinkFigures.add(a); 276 } 277 278 void addInheritanceLinkFigure(InheritanceLinkFigure link) { 279 inheritanceLinkFigures.add(link); 280 } 281 282 void removeInheritanceLinkFigure(InheritanceLinkFigure link) { 283 inheritanceLinkFigures.remove(link); 284 } 285 286 void removeRelationLinkFigure(RelationLinkFigure a) { 287 relationLinkFigures.remove(a); 288 } 289 290 public Vector getRelationLinkFigures() { 291 return relationLinkFigures; 292 } 293 294 void addFieldFigure() { 295 addFieldFigure("newField","void"); 296 } 297 298 /** 299 * Add a new field to the class 300 * @param name the name of the field 301 * @param type the type of the field 302 */ 303 void addFieldFigure(String name, String type) { 304 Field f = new Field(); 305 f.setName(name); 306 f.setType(Projects.types.resolveType(type)); 307 classFig.getCl().addField(f); 308 } 309 310 /* 311 void addFieldFigure(FieldFigure f) { 312 fieldFigures.add(f); 313 } 314 */ 315 316 void addMethodFigure() { 317 Method m = new Method(); 318 m.setName("newMethod"); 319 m.setType(Projects.types.resolveType("void")); 320 classFig.getCl().addMethod(m); 321 } 322 323 void addMethodFigure(MethodFigure f) { 324 methodFigures.add(f); 325 } 326 327 public String getName() { 328 return ((TextFigure)figures().nextFigure()).getText(); 329 } 330 331 /** 332 * Returns all the internal figures of this class (field and 333 * method figures) 334 */ 335 Vector getClassFigures() { 336 Vector ret = new Vector(); 337 ret.add(figures().nextFigure()); 338 ret.addAll(methodFigures); 339 ret.addAll(fieldFigures); 340 return ret; 341 } 342 343 private void initialize() { 344 // fDisplayBox = new Rectangle(0, 0, 0, 0); 345 setZValue(2); 346 } 347 348 /** 349 * Compute the width of the figure, and the position of field and 350 * method figures 351 */ 352 public void layout() { 353 Point partOrigin = (Point)classFig.getCorner().clone(); 354 partOrigin.translate(BORDER, BORDER); 355 Dimension extent = new Dimension(0, 0); 356 357 Iterator it = getClassFigures().iterator(); 358 while(it.hasNext()) { 359 Figure f = (Figure)it.next(); 360 361 Dimension partExtent = f.size(); 362 Point corner = new Point( 363 partOrigin.x+partExtent.width, 364 partOrigin.y+partExtent.height); 365 f.basicDisplayBox(partOrigin, corner); 366 367 extent.width = Math.max(extent.width, partExtent.width); 368 extent.height += partExtent.height; 369 partOrigin.y += partExtent.height; 370 } 371 dimension.width = extent.width + 2*BORDER; 372 dimension.height = extent.height + 2*BORDER; 373 } 374 375 private boolean needsLayout() { 376 /* 377 Dimension extent = new Dimension(0, 0); 378 379 FigureEnumeration k = figures(); 380 while (k.hasMoreElements()) { 381 Figure f = k.nextFigure(); 382 extent.width = Math.max(extent.width, f.size().width); 383 } 384 int newExtent = extent.width + 2*BORDER; 385 return newExtent != fDisplayBox.width; 386 */ 387 return true; 388 } 389 390 public void update(FigureChangeEvent e) { 391 Log.trace("figures",this+".update"); 392 if (needsLayout()) { 393 layout(); 394 changed(); 395 } 396 } 397 398 public void figureChanged(FigureChangeEvent e) { 399 update(e); 400 } 401 402 403 public void figureRemoved(FigureChangeEvent e) { 404 update(e); 405 } 406 407 public void release() { 408 Log.trace("diagram","release "+this); 409 super.release(); 410 close(); 411 if (classFig!=null && classFig.getDiagram()!=null) 412 classFig.getDiagram().removeFigure(classFig); 413 } 414 415 public org.objectweb.jac.ide.ClassFigure getClassFig() { 416 return classFig; 417 } 418 419 public void setClassFig(org.objectweb.jac.ide.ClassFigure classFig) { 420 this.classFig = classFig; 421 initClass(); 422 layout(); 423 } 424 425 public Point getCorner() { 426 return classFig.getCorner(); 427 } 428 429 public ModelElement getSubstance() { 430 return classFig.getCl(); 431 } 432 433 public Class getClassElement() { 434 return classFig.getCl(); 435 } 436 437 // Helper methods 438 public Connector connectorAt(Point p) { 439 return connectorAt(p.x,p.y); 440 } 441 } 442