001 /* 002 Copyright (C) 2002-2003 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.framework.Drawing; 022 import CH.ifa.draw.framework.DrawingEditor; 023 import CH.ifa.draw.framework.DrawingView; 024 import CH.ifa.draw.framework.Figure; 025 import CH.ifa.draw.framework.FigureEnumeration; 026 import CH.ifa.draw.framework.Tool; 027 import CH.ifa.draw.framework.ViewChangeListener; 028 import CH.ifa.draw.standard.ChangeAttributeCommand; 029 import CH.ifa.draw.standard.ChopBoxConnector; 030 import CH.ifa.draw.standard.StandardDrawing; 031 import CH.ifa.draw.util.ColorMap; 032 import CH.ifa.draw.util.CommandChoice; 033 import CH.ifa.draw.util.Filler; 034 import CH.ifa.draw.util.PaletteButton; 035 import CH.ifa.draw.util.PaletteListener; 036 import CH.ifa.draw.util.StandardVersionControlStrategy; 037 import CH.ifa.draw.util.VersionControlStrategy; 038 import CH.ifa.draw.util.VersionManagement; 039 import CH.ifa.draw.util.VersionRequester; 040 import java.awt.BorderLayout; 041 import java.awt.Component; 042 import java.awt.Point; 043 import java.awt.datatransfer.Transferable; 044 import java.awt.dnd.DnDConstants; 045 import java.awt.dnd.DropTarget; 046 import java.awt.dnd.DropTargetDragEvent; 047 import java.awt.dnd.DropTargetDropEvent; 048 import java.awt.dnd.DropTargetEvent; 049 import java.awt.dnd.DropTargetListener; 050 import java.awt.event.ActionEvent; 051 import java.awt.event.ActionListener; 052 import java.awt.event.KeyAdapter; 053 import java.awt.event.KeyEvent; 054 import java.awt.event.MouseAdapter; 055 import java.awt.event.MouseEvent; 056 import java.util.Iterator; 057 import java.util.List; 058 import java.util.Vector; 059 import javax.swing.JComboBox; 060 import javax.swing.JLabel; 061 import javax.swing.JPanel; 062 import javax.swing.JScrollPane; 063 import org.objectweb.jac.aspects.gui.CollectionUpdate; 064 import org.objectweb.jac.aspects.gui.DisplayContext; 065 import org.objectweb.jac.aspects.gui.EventHandler; 066 import org.objectweb.jac.aspects.gui.GuiAC; 067 import org.objectweb.jac.aspects.gui.Transfer; 068 import org.objectweb.jac.aspects.gui.Utils; 069 import org.objectweb.jac.aspects.gui.ViewFactory; 070 import org.objectweb.jac.aspects.gui.swing.AbstractView; 071 import org.objectweb.jac.aspects.gui.swing.SwingEvents; 072 import org.objectweb.jac.core.rtti.ClassRepository; 073 import org.objectweb.jac.core.rtti.CollectionItem; 074 import org.objectweb.jac.ide.Aspect; 075 import org.objectweb.jac.ide.Class; 076 import org.objectweb.jac.ide.Diagram; 077 import org.objectweb.jac.ide.InheritanceLink; 078 import org.objectweb.jac.ide.Link; 079 import org.objectweb.jac.ide.ModelElement; 080 import org.objectweb.jac.ide.Package; 081 import org.objectweb.jac.ide.RelationLink; 082 import org.objectweb.jac.ide.RelationRole; 083 import org.objectweb.jac.ide.TypedElement; 084 import org.objectweb.jac.util.Log; 085 import org.objectweb.jac.util.Strings; 086 087 public class DiagramView extends AbstractView 088 implements DrawingEditor, PaletteListener, VersionRequester, 089 CollectionUpdate, DropTargetListener 090 { 091 static public boolean init = false; 092 093 protected Diagram diagram; 094 095 public DiagramView(ViewFactory factory, DisplayContext context, 096 Object diagram) { 097 super(factory,context); 098 new DropTarget(this, // component 099 DnDConstants.ACTION_COPY_OR_MOVE, // actions 100 this); // DropTargetListener 101 this.diagram = (Diagram)diagram; 102 init(); 103 Utils.registerCollection(diagram,"figures",this); 104 } 105 106 public void close(boolean validate) { 107 Log.trace("diagram","CLOSING DIAGRAM "+this); 108 super.close(validate); 109 FigureEnumeration figures = fDrawing.figures(); 110 while (figures.hasMoreElements()) { 111 Figure f = figures.nextFigure(); 112 if (f instanceof ModelElementFigure) 113 ((ModelElementFigure)f).close(); 114 } 115 Utils.unregisterCollection(diagram,"figures",this); 116 } 117 118 public Object getSubstance() { 119 return diagram; 120 } 121 122 public final Diagram getDiagram() { 123 return diagram; 124 } 125 126 /** 127 * Add a figure for a class at a given location 128 * @param cl the class to add a figure for 129 * @param location where to put the class figure 130 */ 131 public void addClass(Class cl, Point location) { 132 Diagram diagram = (Diagram)getSubstance(); 133 if (diagram.contains(cl)) 134 return; 135 ClassFigure cf = null; 136 org.objectweb.jac.ide.ClassFigure figure = new org.objectweb.jac.ide.ClassFigure(cl); 137 Log.trace("diagram","diagram = "+diagram); 138 diagram.addFigure(figure); 139 Log.trace("diagram","creating new figure "+figure+","+ 140 diagram.getContainer()); 141 cf = new ClassFigure(figure,diagram.getContainer(), 142 view()); 143 (view().add(cf)).displayBox(location,location); 144 } 145 146 /** 147 * Import all relations and inheritance links between a class with 148 * other classes on the diagram 149 * @param cl the class to import relations for 150 */ 151 public void importRelations(Class cl) { 152 Iterator it = diagram.getMissingRelations(cl).iterator(); 153 while (it.hasNext()) { 154 Link relation = (Link)it.next(); 155 try { 156 if (relation instanceof RelationLink) 157 importRelation((RelationLink)relation); 158 else if (relation instanceof InheritanceLink) 159 importInheritance((InheritanceLink)relation); 160 } catch (Exception e) { 161 Log.warning(e.getMessage()); 162 } 163 } 164 } 165 166 /** 167 * Import a relation in the diagram. 168 * @param relation the relation to import 169 * @throws Exception if both classes of the relation are not on the diagram 170 */ 171 public void importRelation(RelationLink relation) throws Exception { 172 ClassFigure endFig = findClass((Class)relation.getEnd()); 173 if (endFig==null) { 174 throw new Exception("Cannot import relation "+GuiAC.toString(relation)+ 175 " since "+GuiAC.toString(relation.getEnd())+ 176 " is not on the diagram"); 177 } 178 ClassFigure startFig = findClass((Class)relation.getStart()); 179 if (startFig==null) { 180 throw new Exception("Cannot import relation "+GuiAC.toString(relation)+ 181 " since "+GuiAC.toString(relation.getStart())+ 182 " is not on the diagram"); 183 } 184 185 org.objectweb.jac.ide.LinkFigure linkFig = new org.objectweb.jac.ide.LinkFigure(relation); 186 diagram.addFigure(linkFig); 187 188 RelationLinkFigure relf = new RelationLinkFigure(); 189 relf.setLinkFigure(linkFig); 190 191 relf.startPoint(startFig.center()); 192 relf.endPoint(endFig.center()); 193 relf.connectStart(startFig.connectorAt(startFig.center())); 194 relf.connectEnd(endFig.connectorAt(endFig.center())); 195 196 relf.updateConnection(); 197 198 view().add(relf); 199 if (relation.getName()!=null && !relation.getName().equals("")) 200 view().add(relf.createName()); 201 if (relation.getEndRole()!=null && !relation.getEndRole().equals("")) 202 view().add(relf.createEndRole()); 203 if (relation.getStartRole()!=null && !relation.getStartRole().equals("")) 204 view().add(relf.createStartRole()); 205 String startCardinality = relation.startRole().getCardinality(); 206 if (startCardinality!=null && !startCardinality.equals("")) 207 view().add(relf.createStartCardinality()); 208 String endCardinality = relation.endRole().getCardinality(); 209 if (endCardinality!=null && !endCardinality.equals("")) 210 view().add(relf.createEndCardinality()); 211 212 Utils.registerObject(relation,relf); 213 } 214 215 /** 216 * Import an inheritance link in the diagram. An exception 217 * @param inheritance the inheritance link to import 218 */ 219 public void importInheritance(InheritanceLink inheritance) throws Exception { 220 ClassFigure endFig = findClass((Class)inheritance.getEnd()); 221 ClassFigure startFig = findClass((Class)inheritance.getStart()); 222 223 org.objectweb.jac.ide.LinkFigure linkFig = new org.objectweb.jac.ide.LinkFigure(inheritance); 224 diagram.addFigure(linkFig); 225 226 InheritanceLinkFigure relf = new InheritanceLinkFigure(); 227 relf.setLinkFigure(linkFig); 228 229 relf.startPoint(startFig.center()); 230 relf.endPoint(endFig.center()); 231 relf.connectStart(startFig.connectorAt(startFig.center())); 232 relf.connectEnd(endFig.connectorAt(endFig.center())); 233 234 relf.updateConnection(); 235 236 view().add(relf); 237 238 Utils.registerObject(inheritance,relf); 239 } 240 241 /** 242 * Create a RelationLink between two classes. 243 * @param source start class of the link 244 * @param target end class of the link 245 * @param linkfigure the figure that represents the relation 246 * @param isAggregation wether the relation is an aggregation 247 */ 248 public void createRelation(Class source, Class target, 249 RelationLinkFigure linkFigure, 250 boolean isAggregation) { 251 Log.trace("figures","creating a new relation link between "+ 252 source+" and "+target); 253 254 RelationLink rel = new RelationLink(); 255 rel.setStart(source); 256 rel.setEnd(target); 257 rel.setAggregation(isAggregation); 258 Log.trace("diagram","1. end="+rel.getEnd()+"===> substance="+target); 259 org.objectweb.jac.ide.LinkFigure linkFig = new org.objectweb.jac.ide.LinkFigure(rel); 260 linkFigure.setLinkFigure(linkFig); 261 view().add(linkFigure.createName()); 262 view().add(linkFigure.createEndRole()); 263 view().add(linkFigure.createStartRole()); 264 view().add(linkFigure.createStartCardinality()); 265 view().add(linkFigure.createEndCardinality()); 266 267 Log.trace("diagram","2. end="+rel.getEnd()); 268 269 if (source==target) { 270 Point c = linkFigure.endFigure().center(); 271 linkFig.addPoint(1,new Point(c.x+100,c.y)); 272 linkFig.addPoint(1,new Point(c.x+100,c.y+100)); 273 linkFig.addPoint(1,new Point(c.x,c.y+100)); 274 } 275 276 diagram.addFigure(linkFig); 277 278 Utils.registerObject(rel,linkFigure); 279 Log.trace("diagram","3. end="+rel.getEnd()); 280 } 281 282 // drop listener interface 283 public void drop(DropTargetDropEvent e) { 284 try { 285 Transferable tr = e.getTransferable(); 286 List transfered = Transfer.getTransferedWrappees(tr); 287 Object o = transfered.get(0); 288 Point location = e.getLocation(); 289 Point offset = scrollPane.getViewport().getViewPosition(); 290 location.translate((int)offset.getX(),(int)offset.getY()); 291 Log.trace("gui.dnd","drop event: "+o); 292 if (o==null) 293 return; 294 if (o instanceof Class) { 295 addClass((Class)o,location); 296 } else if (o instanceof RelationRole) { 297 importRelation((RelationLink)((RelationRole)o).getLink()); 298 } 299 300 } catch(Exception ex) { 301 ex.printStackTrace(); 302 } 303 } 304 public void dragEnter(DropTargetDragEvent e) { } 305 public void dragExit(DropTargetEvent e) { } 306 public void dragOver(DropTargetDragEvent e) { } 307 public void dropActionChanged(DropTargetDragEvent e) { } 308 // end of drop listener interface 309 310 public void figureSelectionChanged(DrawingView view) { 311 if (view.selection().size() > 0) { 312 Figure f = (Figure)view.selection().get(0); 313 314 Log.trace("figures","figure "+f+" selected"); 315 316 if (f instanceof Selectable) { 317 ((Selectable)f).onSelect(getContext()); 318 } 319 320 if (f instanceof ClassFigure) { 321 CollectionItem coll = ClassRepository.get().getClass(Package.class) 322 .getCollection("classes"); 323 EventHandler.get().onSelection( 324 getContext(),coll,((ClassFigure)f).getSubstance(),null,null); 325 326 } else if (f instanceof InstanceFigure) { 327 CollectionItem coll = ClassRepository.get().getClass(Package.class) 328 .getCollection("instances"); 329 EventHandler.get().onSelection( 330 getContext(),coll,((InstanceFigure)f).getSubstance(),null,null); 331 332 } else if (f instanceof GenericObjectFigure) { 333 334 Log.trace("figures","generic object"); 335 EventHandler.get().onSelection( 336 getContext(), 337 ((GenericObjectFigure)f).getCollection(), 338 ((GenericObjectFigure)f).getSubstance(),null,null); 339 340 } else if (f instanceof RelationLinkFigure || 341 f instanceof AttachedTextFigure) { 342 343 RelationLink rel = (RelationLink) 344 ((ModelElementFigure)f).getSubstance(); 345 Class cl = (Class)rel.getStart(); 346 CollectionItem coll = ClassRepository.get().getClass(Package.class) 347 .getCollection("classes"); 348 EventHandler.get().onSelection(getContext(),coll,cl,null,null); 349 coll = ClassRepository.get().getClass(Class.class) 350 .getCollection("relationRoles"); 351 EventHandler.get().onSelection(getContext(),coll, 352 rel.getStartRole(),null,null); 353 //((RelationLinkFigure)f).selectAll(view); 354 355 } else if (f instanceof PointcutLinkFigure) { 356 357 org.objectweb.jac.ide.PointcutLink rel = (org.objectweb.jac.ide.PointcutLink) 358 ((PointcutLinkFigure)f).getSubstance(); 359 org.objectweb.jac.ide.Aspect aspect = (org.objectweb.jac.ide.Aspect)rel.getStart(); 360 CollectionItem coll = ClassRepository.get().getClass(Package.class) 361 .getCollection("aspects"); 362 EventHandler.get().onSelection(getContext(),coll,aspect,null,null); 363 coll = ClassRepository.get().getClass(Aspect.class) 364 .getCollection("pointcutLinks"); 365 EventHandler.get().onSelection(getContext(),coll,rel,null,null); 366 //((PointcutLinkFigure)f).selectAll(view); 367 } 368 } 369 // update(getGraphics()); 370 } 371 372 private transient Drawing fDrawing; 373 private transient Tool fTool; 374 375 private transient DrawingView fView; 376 private transient ToolButton fSelectedToolButton; 377 378 static String fgUntitled = "untitled"; 379 380 ToolPalette classPalette; 381 ToolPalette aspectPalette; 382 ToolPalette instancePalette; 383 ToolPalette groupPalette; 384 ToolPalette currentPalette; 385 386 /** 387 * Find the figure of a given class in the default drawing. 388 * @param cl the Class to search for 389 * @return a ModelElementFigure that matches cl, or null if none is found. 390 */ 391 public ClassFigure findClass(Class cl) { 392 return (ClassFigure)findFigure(view().drawing(),cl); 393 } 394 395 /** 396 * Find the figure of a given model element 397 * @param drawing the Drawing to search the figure into 398 * @param cl the Class to search for 399 * @return a ModelElementFigure that matches cl, or null if none is found. 400 */ 401 public ClassFigure findClass(Drawing drawing, Class cl) { 402 return (ClassFigure)findFigure(drawing,cl); 403 } 404 405 /** 406 * Find the figure of a given model element. 407 * @param drawing the Drawing to search the figure into 408 * @param element the ModelElement to search for 409 * @return a ModelElementFigure that matches element, or null if none is found. 410 */ 411 public ModelElementFigure findFigure(Drawing drawing, ModelElement element) { 412 FigureEnumeration figs = drawing.figures(); 413 while(figs.hasMoreElements()) { 414 Figure fig = figs.nextFigure(); 415 if( (fig instanceof ModelElementFigure) && 416 ((ModelElementFigure)fig).getSubstance() == element) { 417 return (ModelElementFigure)fig; 418 } 419 } 420 return null; 421 } 422 423 /** 424 * Find the figure of a given TypedElement 425 */ 426 public Figure findElement(TypedElement te) { 427 FigureEnumeration figs = view().drawing().figures(); 428 while(figs.hasMoreElements()) { 429 Figure fig = figs.nextFigure(); 430 if( (fig instanceof ModelElementFigure) && 431 ((ModelElementFigure)fig).getSubstance() == te) { 432 return fig; 433 } 434 } 435 return null; 436 } 437 438 /** 439 * Find the figure of a given ModelElement 440 */ 441 public Figure findElement(ModelElement element) { 442 FigureEnumeration figs = view().drawing().figures(); 443 while(figs.hasMoreElements()) { 444 Figure fig = figs.nextFigure(); 445 if( (fig instanceof ModelElementFigure) && 446 ((ModelElementFigure)fig).getSubstance() == element) { 447 return fig; 448 } 449 } 450 return null; 451 } 452 453 JScrollPane scrollPane; 454 /** 455 * Initializes the applet and creates its contents. 456 */ 457 public void init() { 458 //DiagramView.display = display; 459 //diagramViews.add(this); 460 461 getVersionControlStrategy().assertCompatibleVersion(); 462 463 setLayout(new BorderLayout()); 464 465 fView = createDrawingView(); 466 467 try { 468 buildClassBar(); 469 } catch (Exception e) { 470 e.printStackTrace(); 471 } 472 473 scrollPane = new JScrollPane((Component)view()); 474 add("Center", scrollPane); 475 JPanel buttonPalette = createButtonPanel(); 476 createButtons(buttonPalette); 477 add("North", buttonPalette); 478 setToolBar(buildClassBar()); 479 480 initDrawing(); 481 // JFC should have its own internal double buffering... 482 //setBufferedDisplayUpdate(); 483 //setupAttributes(); 484 load(); 485 //((JComponent)drawing()).setMinimumSize(new Dimension(2000,2000)); 486 } 487 488 public void addViewChangeListener(ViewChangeListener vsl) { 489 } 490 491 public void removeViewChangeListener(ViewChangeListener vsl) { 492 } 493 494 495 /** 496 * Creates the color choice for the given attribute. 497 */ 498 protected JComboBox createColorChoice(String attribute) { 499 CommandChoice choice = new CommandChoice(); 500 for (int i = 0; i < ColorMap.size(); i++) 501 choice.addItem( 502 new ChangeAttributeCommand( 503 ColorMap.name(i), 504 attribute, 505 ColorMap.color(i), 506 this 507 ) 508 ); 509 return choice; 510 } 511 512 /** 513 * Creates the buttons panel. 514 */ 515 protected JPanel createButtonPanel() { 516 JPanel panel = new JPanel(); 517 panel.setLayout(new PaletteLayout(2, new Point(2,2), false)); 518 return panel; 519 } 520 521 /** 522 * Sets the tool bar containing tool buttons. 523 */ 524 void setToolBar(ToolPalette newPalette) { 525 if (currentPalette != null) { 526 remove(currentPalette); 527 } 528 add(BorderLayout.WEST, newPalette); 529 currentPalette = newPalette; 530 validate(); 531 } 532 533 ToolPalette buildClassBar() { 534 Log.trace("diagram","BUILDING CLASS BAR"); 535 classPalette = new ToolPalette(); 536 537 classPalette.setDefaultToolButton( 538 classPalette.addToolButton(this, "icon_selection", "Selection Tool", 539 createSelectionTool())); 540 541 classPalette.addToolButton(this, "icon_text", "Text Tool", 542 new TextTool(this, new TextFigure())); 543 classPalette.addToolButton(this, "icon_class", "Create a new class", 544 new NewClassFigureCreationTool(this,getContext())); 545 classPalette.addToolButton(this, "icon_import_class", "Add an existing class", 546 new ClassFigureCreationTool(this,getContext())); 547 try { 548 classPalette.addToolButton(this, "icon_see_relation", "Show existing relation", 549 new RelationLinkShowTool(this,getContext())); 550 } catch (ClassNotFoundException e) { 551 e.printStackTrace(); 552 } 553 classPalette.addToolButton(this, "icon_relation", "New relation link", 554 new RelationLinkCreationTool(this)); 555 classPalette.addToolButton(this, "icon_add_point", "Add a point", 556 new ConnectionTool(this, new RelationLinkFigure())); 557 classPalette.addToolButton(this, "icon_inheritance", "Inheritance link", 558 new InheritanceLinkCreationTool(this)); 559 classPalette.addToolButton(this, "icon_field", "Create new attribute", 560 new FieldCreationTool(this,getContext())); 561 classPalette.addToolButton(this, "icon_method", "Create new method", 562 new MethodCreationTool(this,getContext())); 563 return classPalette; 564 } 565 566 ToolPalette buildAspectBar() { 567 Log.trace("diagram","BUILDING ASPECT BAR"); 568 569 aspectPalette = new ToolPalette(); 570 571 aspectPalette.setDefaultToolButton( 572 aspectPalette.addToolButton(this, "icon_selection", "Selection Tool", 573 createSelectionTool())); 574 575 aspectPalette.addToolButton(this, "icon_text", "Text Tool", 576 new TextTool(this, new TextFigure())); 577 aspectPalette.addToolButton(this, "icon_aspect", "Create a new aspect", 578 new NewAspectFigureCreationTool(this,getContext())); 579 aspectPalette.addToolButton(this, "icon_import_aspect", "Add an existing aspect", 580 new AspectFigureCreationTool(this,getContext())); 581 aspectPalette.addToolButton(this, "icon_pointcut", "New pointcut link", 582 new PointcutLinkCreationTool(this, new PointcutLinkFigure())); 583 aspectPalette.addToolButton(this, "icon_see_pointcut", "Show existing pointcut", 584 new PointcutLinkShowTool(this,getContext())); 585 aspectPalette.addToolButton(this, "icon_add_point", "Add a point", 586 new ConnectionTool(this, new RelationLinkFigure())); 587 aspectPalette.addToolButton(this, "icon_field", "Create new attribute", 588 new FieldCreationTool(this,getContext())); 589 aspectPalette.addToolButton(this, "icon_method", "Create new configuration method", 590 new MethodCreationTool(this,getContext())); 591 aspectPalette.addToolButton(this, "icon_aspect_method","Create new aspect method", 592 new MethodCreationTool(this,getContext())); 593 return aspectPalette; 594 } 595 596 ToolPalette buildInstanceBar() { 597 Log.trace("diagram","BUILDING INSTANCE BAR"); 598 599 instancePalette = new ToolPalette(); 600 601 instancePalette.setDefaultToolButton( 602 instancePalette.addToolButton(this, "icon_selection", "Selection Tool", 603 createSelectionTool())); 604 instancePalette.addToolButton(this, "icon_text", "Text Tool", 605 new TextTool(this, new TextFigure())); 606 instancePalette.addToolButton(this, "icon_instance", "Create a new instance", 607 new NewInstanceFigureCreationTool(this,getContext())); 608 instancePalette.addToolButton(this, "icon_import_instance", "Add an existing instance", 609 new InstanceFigureCreationTool(this,getContext())); 610 return instancePalette; 611 } 612 613 ToolPalette buildGroupBar() { 614 Log.trace("diagram","BUILDING GROUP BAR"); 615 616 groupPalette = new ToolPalette(); 617 618 groupPalette.setDefaultToolButton( 619 groupPalette.addToolButton(this,"icon_selection", "Selection Tool", 620 createSelectionTool())); 621 groupPalette.addToolButton(this,"icon_text", "Text Tool", 622 new TextTool(this, new TextFigure())); 623 groupPalette.addToolButton(this, "icon_group", "Create a new group", 624 new NewInstanceFigureCreationTool(this,getContext())); 625 groupPalette.addToolButton(this, "icon_import_group", "Add an existing group", 626 new GroupFigureShowTool(this,getContext())); 627 return groupPalette; 628 } 629 630 /** 631 * Creates the buttons shown in the buttons panel. Override to 632 * add additional buttons. 633 * @param panel the buttons panel. 634 */ 635 protected void createButtons(JPanel panel) { 636 panel.add(new Filler(24,20)); 637 JLabel title = new JLabel(GuiAC.toString(diagram)+" diagram "); 638 panel.add(title); 639 640 panel.add(new Filler(6,20)); 641 642 JComboBox combo = new JComboBox(new Object[] { 643 "class mode", 644 "aspect mode", 645 "instance mode", 646 "group mode"} 647 ); 648 649 combo.addActionListener( 650 new ActionListener() { 651 public void actionPerformed(ActionEvent event) { 652 JComboBox cb = (JComboBox)event.getSource(); 653 String command = (String)cb.getSelectedItem(); 654 if (command.equals("class mode")) { 655 setToolBar(buildClassBar()); 656 } else if (command.equals("aspect mode")) { 657 setToolBar(buildAspectBar()); 658 } else if (command.equals("instance mode")) { 659 setToolBar(buildInstanceBar()); 660 } else if (command.equals("group mode")) { 661 setToolBar(buildGroupBar()); 662 } 663 setSelected(currentPalette.getDefaultToolButton()); 664 } 665 } 666 ); 667 668 panel.add(combo); 669 coord = new JLabel("(--,--)"); 670 panel.add(coord); 671 } 672 673 JLabel coord; 674 public void setCoord(int x, int y) { 675 coord.setText("("+x+","+y+")"); 676 } 677 678 /** 679 * Creates the tools palette. 680 */ 681 protected JPanel createToolPalette() { 682 JPanel palette = new JPanel(); 683 palette.setLayout(new PaletteLayout(2,new Point(2,2))); 684 return palette; 685 } 686 687 /** 688 * Creates the selection tool used in this editor. Override to use 689 * a custom selection tool. 690 */ 691 protected Tool createSelectionTool() { 692 return new SelectionTool(this,getContext()); 693 } 694 695 /** 696 * Creates the drawing used in this application. 697 * You need to override this method to use a Drawing 698 * subclass in your application. By default a standard 699 * Drawing is returned. 700 */ 701 protected Drawing createDrawing() { 702 return new StandardDrawing(); 703 } 704 705 /** 706 * Creates the drawing view used in this application. 707 * You need to override this method to use a DrawingView 708 * subclass in your application. By default a standard 709 * DrawingView is returned. 710 */ 711 protected DrawingView createDrawingView() { 712 IDEDrawingView view = new IDEDrawingView(this, 2000, 2000); 713 view.addMouseListener( 714 new MouseAdapter() { 715 public void mousePressed(MouseEvent e) { 716 // Show popup menu 717 if (e.isPopupTrigger()) { 718 Figure figure = drawing().findFigure(e.getX(), e.getY()); 719 if (figure instanceof ModelElementFigure) { 720 ModelElement element = 721 ((ModelElementFigure)figure).getSubstance(); 722 if (figure instanceof ClassFigure) { 723 Figure memberFigure = figure.findFigureInside(e.getX(), e.getY()); 724 if (memberFigure instanceof MemberFigure) { 725 SwingEvents.showObjectsMenu( 726 getContext(), 727 new Object[] {((ClassFigure)figure).getClassFig(), 728 element, 729 ((MemberFigure)memberFigure).getSubstance()}, 730 e); 731 } else { 732 SwingEvents.showObjectsMenu( 733 getContext(), new Object[] {((ClassFigure)figure).getClassFig(),element}, e); 734 } 735 } else { 736 SwingEvents.showObjectMenu(getContext(), element, e); 737 } 738 } 739 } 740 } 741 } 742 ); 743 744 view.addKeyListener( 745 new KeyAdapter() { 746 public void keyPressed(KeyEvent e) { 747 int code = e.getKeyCode(); 748 if ((code == KeyEvent.VK_BACK_SPACE) || 749 (code == KeyEvent.VK_DELETE)) 750 { 751 Log.trace("ide.diagram","DELETE"); 752 Vector selection = view().selection(); 753 for (int i=0; i<selection.size(); i++) { 754 Figure figure = (Figure)selection.get(i); 755 if (figure instanceof ClassFigure || 756 figure instanceof LinkFigure) { 757 Log.trace("ide.diagram","removing "+figure); 758 ModelElement element = 759 ((ModelElementFigure)figure).getSubstance(); 760 diagram.removeElement(element); 761 } 762 if (e.isControlDown()) { 763 Log.trace("ide.diagram","DELETE REAL"); 764 if (figure instanceof ClassFigure) { 765 Class cl = 766 (Class)((ModelElementFigure)figure).getSubstance(); 767 cl.getContainer().removeClass(cl); 768 } else if (figure instanceof RelationLinkFigure) { 769 RelationLink link = 770 (RelationLink)((ModelElementFigure)figure).getSubstance(); 771 link.setStart(null); 772 link.setEnd(null); 773 } else if (figure instanceof InheritanceLinkFigure) { 774 InheritanceLink link = 775 (InheritanceLink)((ModelElementFigure)figure).getSubstance(); 776 ((Class)link.getStart()).setSuperClass(null); 777 } 778 } 779 } 780 view().clearSelection(); 781 } 782 } 783 } 784 ); 785 return view; 786 } 787 788 /** 789 * Handles a user selection in the palette. 790 * @see PaletteListener 791 */ 792 public void paletteUserSelected(PaletteButton button) { 793 ToolButton toolButton = (ToolButton)button; 794 Log.trace("palette","paletteUserSelected "+toolButton.getTool()); 795 setTool(toolButton.getTool(), toolButton.getName()); 796 setSelected(toolButton); 797 } 798 799 /** 800 * Handles when the mouse enters or leaves a palette button. 801 * @see PaletteListener 802 */ 803 public void paletteUserOver(PaletteButton button, boolean inside) { 804 if (inside) { 805 showStatus(((ToolButton)button).name()); 806 } else { 807 if(fSelectedToolButton==null) { 808 showStatus(""); 809 } else { 810 showStatus(fSelectedToolButton.name()); 811 } 812 } 813 } 814 815 /** 816 * Gets the current drawing. 817 * @see DrawingEditor 818 */ 819 public Drawing drawing() { 820 return fDrawing; 821 } 822 823 /** 824 * Gets the current tool. 825 * @see DrawingEditor 826 */ 827 public Tool tool() { 828 return fTool; 829 } 830 831 /** 832 * Gets the current drawing view. 833 * @see DrawingEditor 834 */ 835 public DrawingView view() { 836 return fView; 837 } 838 839 public DrawingView[] views() { 840 return new DrawingView[] { view() } ; 841 } 842 843 /** 844 * Sets the default tool of the editor. 845 * @see DrawingEditor 846 */ 847 public void toolDone() { 848 if (currentPalette!=null) { 849 ToolButton button = currentPalette.getDefaultToolButton(); 850 if (button!=null) { 851 setTool(button.getTool(), button.getName()); 852 setSelected(button); 853 } 854 } 855 } 856 857 public void viewSelectionChanged(DrawingView oldView, DrawingView newView) { 858 } 859 860 private void initDrawing() { 861 fDrawing = createDrawing(); 862 view().setDrawing(fDrawing); 863 toolDone(); 864 } 865 866 private void setTool(Tool t, String name) { 867 Log.trace("palette","setTool "+t+" current="+fTool); 868 if (fTool != null) { 869 fTool.deactivate(); 870 } 871 fTool = t; 872 if (fTool != null) { 873 showStatus(name); 874 fTool.activate(); 875 } 876 } 877 878 private void setSelected(ToolButton button) { 879 if (fSelectedToolButton != null) { 880 fSelectedToolButton.reset(); 881 } 882 fSelectedToolButton = button; 883 if (fSelectedToolButton != null) { 884 fSelectedToolButton.select(); 885 } 886 } 887 888 protected VersionControlStrategy getVersionControlStrategy() { 889 return new StandardVersionControlStrategy(this); 890 } 891 892 /** 893 * Subclasses should override this method to specify to which versions of 894 * JHotDraw they are compatible. A string array is returned so it is possible 895 * to specify several version numbers of JHotDraw to which the application 896 * is compatible with. 897 * 898 * @return all versions number of JHotDraw the application is compatible with. 899 */ 900 public String[] getRequiredVersions() { 901 String[] requiredVersions = new String[1]; 902 // return the version of the package we are in 903 requiredVersions[0] = 904 VersionManagement.getPackageVersion(DiagramView.class.getPackage()); 905 return requiredVersions; 906 } 907 908 /** 909 * Initialize from the org.objectweb.jac.ide.Diagram 910 */ 911 public void load() { 912 toolDone(); 913 914 if (diagram == null) { 915 Log.error("no diagram"); 916 return; 917 } 918 919 init=true; 920 921 try { 922 Log.trace("diagram","initializing drawing"); 923 fDrawing.release(); 924 fDrawing = new StandardDrawing(); 925 Vector links = new Vector(); 926 Vector ilinks = new Vector(); 927 Iterator i = getDiagram().getFigures().iterator(); 928 while (i.hasNext()) { 929 Object figure = i.next(); 930 try { 931 if (figure instanceof org.objectweb.jac.ide.ClassFigure) { 932 if (((org.objectweb.jac.ide.ClassFigure)figure).getCl() 933 instanceof org.objectweb.jac.ide.Aspect) { 934 fDrawing.add( 935 new AspectFigure((org.objectweb.jac.ide.ClassFigure)figure, 936 getDiagram().getContainer(), 937 view())); 938 } else { 939 fDrawing.add( 940 new ClassFigure((org.objectweb.jac.ide.ClassFigure)figure, 941 getDiagram().getContainer(), 942 view())); 943 } 944 } else if (figure instanceof org.objectweb.jac.ide.LinkFigure) { 945 Figure linkFigure = null; 946 Link link = ((org.objectweb.jac.ide.LinkFigure)figure).getLink(); 947 if (link instanceof org.objectweb.jac.ide.RelationLink) { 948 linkFigure = 949 new RelationLinkFigure((org.objectweb.jac.ide.LinkFigure)figure); 950 } else if (link instanceof org.objectweb.jac.ide.PointcutLink) { 951 linkFigure = 952 new PointcutLinkFigure((org.objectweb.jac.ide.LinkFigure)figure); 953 } else if (link instanceof org.objectweb.jac.ide.InheritanceLink) { 954 linkFigure = 955 new InheritanceLinkFigure((org.objectweb.jac.ide.LinkFigure)figure); 956 } 957 links.add(linkFigure); 958 } 959 } catch(Exception e) { 960 Log.error("cannot load figure "+figure); 961 e.printStackTrace(); 962 } 963 } 964 965 // connect links 966 i = links.iterator(); 967 while (i.hasNext()) { 968 LinkFigure linkFigure = (LinkFigure)i.next(); 969 Log.trace("diagram","importing link "+linkFigure); 970 Link link = (Link)linkFigure.getSubstance(); 971 ClassFigure start = findClass(fDrawing,(Class)link.getStart()); 972 Log.trace("diagram","link start "+link.getStart()+" -> "+start); 973 if (start!=null) { 974 linkFigure.connectStart(new ChopBoxConnector(start)); 975 linkFigure.startPoint(start.getCorner().x,start.getCorner().y); 976 } 977 ClassFigure end = findClass(fDrawing,(Class)link.getEnd()); 978 Log.trace("diagram","link end "+link.getEnd()+" -> "+end); 979 if (end!=null) { 980 linkFigure.connectEnd(new ChopBoxConnector(end)); 981 linkFigure.endPoint(end.getCorner().x,end.getCorner().y); 982 } 983 if (start!=null && end!=null) 984 linkFigure.updateConnection(); 985 if (start!=null && end!=null) { 986 fDrawing.add(linkFigure); 987 linkFigure.load(fDrawing); 988 } else { 989 Log.warning("diagram", 990 "Bad link: start = "+link.getStart()+" -> "+start+ 991 "; end = "+link.getEnd()+" -> "+end); 992 } 993 } 994 995 // connect ilinks 996 /*i = ilinks.iterator(); 997 while (i.hasNext()) { 998 InheritanceLinkFigure linkFigure 999 = (InheritanceLinkFigure)i.next(); 1000 Log.trace("diagram","importing link "+linkFigure); 1001 Link link = (Link)linkFigure.getLinkFigure().getLink(); 1002 ClassFigure start = findClass(fDrawing,(Class)link.getStart()); 1003 Log.trace("diagram","link start "+link.getStart()+" -> "+start); 1004 if (start!=null) { 1005 linkFigure.connectStart(new ChopBoxConnector(start)); 1006 linkFigure.startPoint(start.getCorner().x,start.getCorner().y); 1007 } 1008 ClassFigure end = findClass(fDrawing,(Class)link.getEnd()); 1009 Log.trace("diagram","link start "+link.getEnd()+" -> "+end); 1010 if (end!=null) { 1011 linkFigure.connectEnd(new ChopBoxConnector(end)); 1012 linkFigure.endPoint(end.getCorner().x,end.getCorner().y); 1013 } 1014 linkFigure.updateConnection(); 1015 fDrawing.add(linkFigure); 1016 linkFigure.load(fDrawing); 1017 }*/ 1018 1019 Log.trace("diagram","sets the drawing"); 1020 view().setDrawing(fDrawing); 1021 toolDone(); 1022 } catch (Exception e) { 1023 initDrawing(); 1024 e.printStackTrace(); 1025 showStatus("Error:" + e); 1026 } finally { 1027 init=false; 1028 } 1029 } 1030 1031 public void showStatus(String msg) { 1032 if (getContext()!=null) { 1033 getContext().getCustomizedView().showStatus(msg); 1034 } 1035 if (!Strings.isEmpty(msg)) 1036 Log.trace("diagram","Status: "+msg); 1037 } 1038 1039 public String toString() { 1040 return Strings.hex(this); 1041 } 1042 1043 // CollectionUpdate interface 1044 1045 public void onChange(Object substance, 1046 CollectionItem collection, Object value, 1047 Object param) { 1048 } 1049 1050 public void onAdd(Object substance, 1051 CollectionItem collection, Object value, 1052 Object added, Object param) { 1053 } 1054 1055 public void onRemove(Object substance, CollectionItem collection, Object value, 1056 Object removed, Object param) { 1057 Log.trace("diagram.remove","onRemove "+removed); 1058 org.objectweb.jac.ide.Figure removedFigure = (org.objectweb.jac.ide.Figure)removed; 1059 ModelElementFigure figure = findFigure(fDrawing,removedFigure.getElement()); 1060 Log.trace("diagram.remove","figure = "+figure); 1061 if (figure!=null) { 1062 Figure fig = fDrawing.remove((Figure)figure); 1063 view().removeFromSelection(figure); 1064 Log.trace("diagram.remove","removed "+fig); 1065 view().repairDamage(); 1066 } 1067 } 1068 1069 }