001 /* 002 Copyright (C) 2002-2003 Renaud Pawlak <renaud@aopsys.com>, 003 Laurent Martelli <laurent@aopsys.com> 004 005 This program is free software; you can redistribute it and/or modify 006 it under the terms of the GNU Lesser General Public License as 007 published by the Free Software Foundation; either version 2 of the 008 License, or (at your option) any later version. 009 010 This program is distributed in the hope that it will be useful, but 011 WITHOUT ANY WARRANTY; without even the implied warranty of 012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 Lesser General Public License for more details. 014 015 You should have received a copy of the GNU Lesser General Public 016 License along with this program; if not, write to the Free Software 017 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 018 USA */ 019 020 package org.objectweb.jac.aspects.gui; 021 022 import java.lang.reflect.Array; 023 import java.lang.reflect.Modifier; 024 import java.util.Arrays; 025 import java.util.Collection; 026 import java.util.Hashtable; 027 import java.util.Iterator; 028 import java.util.Map; 029 import java.util.Vector; 030 import org.apache.log4j.Logger; 031 import org.objectweb.jac.core.Collaboration; 032 import org.objectweb.jac.core.Naming; 033 import org.objectweb.jac.core.ObjectRepository; 034 import org.objectweb.jac.core.Wrappee; 035 import org.objectweb.jac.core.rtti.AbstractMethodItem; 036 import org.objectweb.jac.core.rtti.ClassItem; 037 import org.objectweb.jac.core.rtti.ClassRepository; 038 import org.objectweb.jac.core.rtti.CollectionItem; 039 import org.objectweb.jac.core.rtti.FieldItem; 040 import org.objectweb.jac.core.rtti.MetaItem; 041 import org.objectweb.jac.core.rtti.MethodItem; 042 import org.objectweb.jac.core.rtti.MixinMethodItem; 043 import org.objectweb.jac.core.rtti.RttiAC; 044 import org.objectweb.jac.core.rtti.VirtualClassItem; 045 import org.objectweb.jac.util.Classes; 046 import org.objectweb.jac.util.Enum; 047 import org.objectweb.jac.util.ExtArrays; 048 import org.objectweb.jac.util.ExtBoolean; 049 import org.objectweb.jac.util.NotInCollectionPredicate; 050 import org.objectweb.jac.util.Predicate; 051 import org.objectweb.jac.util.Stack; 052 import org.objectweb.jac.util.Strings; 053 054 /** 055 * This class implements static methods that generically create GUI 056 * items. Depending on the actual view factory, the created items are 057 * for SWING, WEB or other GUI. */ 058 059 public class GenericFactory { 060 static Logger logger = Logger.getLogger("gui.generic"); 061 static Logger loggerAssoc = Logger.getLogger("associations"); 062 063 /** 064 * Creates a view on an object. 065 * 066 * @param factory the used factory 067 * @param context the display context (passed to ceated sub-item so 068 * that they know displays and customized) 069 * @param viewName name of the view to build 070 * @param substance the object to build a view of */ 071 072 public static View createObjectView( 073 ViewFactory factory, 074 DisplayContext context, 075 String viewName, 076 Object substance) 077 { 078 logger.debug("createObjectView(" 079 + factory + "," + Strings.hex(substance) + "," + viewName + ")"); 080 081 if (substance == null) { 082 return factory.createView("null", "Empty", context); 083 } 084 085 if (substance instanceof Number 086 || substance instanceof Boolean 087 || substance instanceof Character 088 || substance instanceof String) { 089 return factory.createView( 090 substance.getClass().getName(), 091 "Field", 092 new Object[] { substance, null, null }, 093 context); 094 } 095 096 Class substance_type = substance.getClass(); 097 ClassItem cli = ClassRepository.get().getClass(substance_type); 098 099 CompositeView view = 100 (CompositeView) factory.createCompositeView( 101 cli.getName(), 102 "ObjectView", 103 context); 104 105 fillObjectView(view, cli, viewName, substance); 106 Collection dependencies = GuiAC.getDependentFields(cli); 107 if (dependencies != null) { 108 Iterator it = dependencies.iterator(); 109 while (it.hasNext()) { 110 FieldItem field = (FieldItem) it.next(); 111 Utils.registerField(substance, field, EventHandler.get(), view); 112 } 113 } 114 return view; 115 } 116 117 public static void fillObjectView( 118 CompositeView view, 119 ClassItem cli, 120 String viewName, 121 Object substance) 122 { 123 ObjectView objectView = GuiAC.getView(cli, viewName); 124 ViewFactory factory = view.getFactory(); 125 DisplayContext context = view.getContext(); 126 String[] categories = (String[]) cli.getAttribute(GuiAC.CATEGORIES); 127 String[] icons = GuiAC.getCategoriesIcons(cli); 128 String[] labels = GuiAC.getCategoriesLabels(cli); 129 if (labels == null) 130 labels = categories; 131 132 view.setStyle((String) cli.getAttribute(GuiAC.STYLE)); 133 view.setDescription(GuiAC.getDescription(substance, "<b>", "</b>")); 134 135 logger.debug("categories = " 136 + (categories != null 137 ? Arrays.asList(categories).toString() 138 : "null")); 139 140 if (categories == null) { 141 view.addView( 142 createObjectView( 143 factory, 144 context, 145 objectView, 146 substance, 147 null)); 148 } else { 149 TabsView tabbedPane = 150 (TabsView) factory.createCompositeView( 151 cli.getName(), 152 "Tabbed", 153 context); 154 for (int i = 0; i < categories.length; i++) { 155 logger.debug("add tab for category " + categories[i]); 156 157 String icon; 158 if ((icons != null) && (Array.getLength(icons) > i)) 159 icon = icons[i]; 160 else 161 icon = null; 162 163 CompositeView tab = 164 createObjectView( 165 factory, 166 context, 167 objectView, 168 substance, 169 categories[i]); 170 if (!compositeViewIsEmpty(tab)) 171 tabbedPane.addTab(tab, labels[i], icon); 172 else 173 logger.debug("tab[" + categories[i] + "] is empty"); 174 } 175 view.addView((CompositeView) tabbedPane); 176 } 177 } 178 179 /** 180 * Creates a view of an object (containing no tabs). 181 * 182 * @param factory the used factory 183 * @param context the display context (passed to ceated sub-item so 184 * that they know displays and customized) 185 * @param substance the viewed object */ 186 187 public static View createObjectViewNoTab( 188 ViewFactory factory, 189 DisplayContext context, 190 Object substance) 191 { 192 logger.debug("createObjectViewNoTab(" 193 + factory 194 + "," 195 + Strings.hex(substance) 196 + ")"); 197 198 if (substance == null) { 199 return factory.createView( 200 substance.getClass().getName(), 201 "Empty", 202 context); 203 } else { 204 return createObjectView( 205 factory, 206 context, 207 GuiAC.getView( 208 ClassRepository.get().getClass(substance), 209 "default"), 210 substance, 211 null); 212 } 213 } 214 215 /** 216 * Returns true is the CompositeView contains a view other than 217 * CompositeView. 218 */ 219 public static boolean compositeViewIsEmpty(CompositeView view) { 220 Iterator it = view.getViews().iterator(); 221 while (it.hasNext()) { 222 View subView = (View) it.next(); 223 if (!(subView instanceof CompositeView)) 224 return false; 225 else if (!compositeViewIsEmpty((CompositeView) subView)) 226 return false; 227 } 228 return true; 229 } 230 231 /** 232 * Create a view of an object, including only the attributes of a 233 * category. 234 * 235 * @param factory the ViewFactory 236 * @param context the DisplayContext 237 * @param substance the object to build the view of 238 * @param category the category; if null, all fields are shown 239 * @return a CompositeView representing the object 240 */ 241 protected static CompositeView createObjectView( 242 ViewFactory factory, 243 DisplayContext context, 244 ObjectView view, 245 Object substance, 246 String category) 247 { 248 logger.debug("createObjectView(" 249 + factory + "," + Strings.hex(substance) + "," 250 + category+ "," + view.getName() + ")"); 251 CompositeView resultPane = 252 factory.createCompositeView( 253 substance.getClass().getName() + "[" + category + "]", 254 "Container", 255 new Object[] { new Integer(Constants.VERTICAL)}, 256 context); 257 258 Class substance_type = substance.getClass(); 259 ClassItem cli = ClassRepository.get().getClass(substance_type); 260 261 CompositeView fieldpane = 262 factory.createCompositeView( 263 "fields", 264 "ParameterContainer", 265 new Object[] { Boolean.TRUE }, 266 context); 267 // EditorContainer editorContainer = (EditorContainer)fieldpane; 268 269 // primitive fields and references 270 271 FieldItem[] fields = null; 272 fields = view.getAttributesOrder(); 273 if (fields == null) 274 fields = cli.getFields(); 275 276 boolean embedded = view.getName().equals(GuiAC.AUTOCREATE_VIEW); 277 logger.debug("attributes_order = " + Arrays.asList(fields)); 278 FieldItem[] groups = (FieldItem[]) cli.getAttribute(GuiAC.LINE_BREAKS); 279 int curgroup = 0; 280 281 CompositeView subFieldPane = null; 282 FieldItem oppositeRole = 283 (FieldItem) Collaboration.get().getAttribute(GuiAC.OPPOSITE_ROLE); 284 loggerAssoc.debug("opposite role = " + oppositeRole); 285 boolean first = true; 286 for (int i = 0; i < fields.length; i++) { 287 if (groups != null 288 && curgroup < groups.length 289 && groups[curgroup] == fields[i]) { 290 if (subFieldPane != null) { 291 fieldpane.addView(subFieldPane); 292 } 293 subFieldPane = 294 factory.createCompositeView( 295 "subField[" + i + "]", 296 "Container", 297 new Object[] { new Integer(Constants.HORIZONTAL)}, 298 context); 299 first = true; 300 curgroup++; 301 } 302 FieldItem field = fields[i]; 303 //if(field==null) continue; 304 if (GuiAC.isMemberInCategory(field, category) 305 && GuiAC.isVisible(substance, field) 306 && !field.isStatic() 307 && !field.equals(oppositeRole)) { 308 CompositeView pane = 309 subFieldPane != null ? subFieldPane : fieldpane; 310 try { 311 if (!first && subFieldPane != null) 312 subFieldPane.addHorizontalStrut(10); 313 pane.addView( 314 getFieldPane( 315 factory, 316 context, 317 substance, 318 view, 319 field, 320 embedded)); 321 first = false; 322 } catch (Exception e) { 323 logger.error( 324 "Failed to build view for field \""+field+"\"", e); 325 } 326 } 327 } 328 if (subFieldPane != null) { 329 fieldpane.addView(subFieldPane); 330 } 331 332 resultPane.addView(fieldpane); 333 334 logger.debug("getMethodsPane for " + cli); 335 336 Collection meths = new Vector(); 337 //if (Collaboration.get().getAttribute(GuiAC.AUTO_CREATION) == null) { 338 MethodItem[] ms = view.getMethodsOrder(); 339 if (ms != null) { 340 meths = Arrays.asList(ms); 341 } 342 //} 343 344 logger.debug("methods = " + meths); 345 346 CompositeView methodsPane = 347 getMethodsPane(factory, context, substance, meths, category, view); 348 if (methodsPane != null) { 349 logger.debug("adding methodPane"); 350 resultPane.addView(methodsPane); 351 } 352 353 return resultPane; 354 355 } 356 357 public static View getFieldPane( 358 ViewFactory factory, 359 DisplayContext context, 360 Object substance, 361 ObjectView objectView, 362 FieldItem field, 363 boolean embedded) 364 { 365 GuiAC.pushGraphicContext(field); 366 try { 367 MemberItemView memberView = GuiAC.getView(field, objectView.getName()); 368 if (field.isReference()) { 369 return getReferenceFieldPane( 370 factory, 371 context, 372 substance, 373 field, 374 embedded, 375 objectView,memberView); 376 } else if (field.isPrimitive() 377 || factory.hasViewerFor(field.getTypeItem().getName())) { 378 return getPrimitiveFieldPane( 379 factory, 380 context, 381 substance, 382 field, 383 objectView, 384 memberView, 385 embedded); 386 } else if (field instanceof CollectionItem) { 387 return getCollectionPane( 388 factory, 389 context, 390 substance, 391 objectView, 392 (CollectionItemView) memberView, 393 (CollectionItem) field); 394 } 395 } finally { 396 GuiAC.popGraphicContext(); 397 } 398 return null; 399 } 400 401 /** 402 * Instantiates a viewer for a value of a field and add it to a 403 * container. 404 */ 405 protected static boolean getViewer( 406 Object substance, 407 FieldItem field, 408 Object value, 409 CompositeView container, 410 ViewFactory factory, 411 DisplayContext context) 412 { 413 Stack types = new Stack(); 414 types.push(ClassRepository.get().getClass(field.getType())); 415 if (value != null) { 416 ClassItem actualClass = ClassRepository.get().getClass(value); 417 if (types.safeTop()!=actualClass) 418 types.push(actualClass); 419 } 420 421 Enum enum = GuiAC.getEnum(field); 422 if (enum!=null) { 423 types.push(ClassRepository.get().getVirtualClass("Enum")); 424 } 425 426 MetaItem type = RttiAC.getFieldType(field,substance); 427 if (type!=null && types.safeTop()!=type) 428 types.push(type); 429 430 logger.debug("types = " + types); 431 boolean foundViewer = false; 432 while (!types.empty()) { 433 type = (MetaItem) types.pop(); 434 if (factory.hasViewerFor(type.getName())) { 435 container.addView( 436 factory.createView( 437 field.getName(), 438 type.getName(), 439 new Object[] { value, substance, field }, 440 context)); 441 foundViewer = true; 442 break; 443 } 444 } 445 return foundViewer; 446 } 447 448 /** 449 * Returns a view of a primitive field. It contains a label and the 450 * value of the field. 451 * 452 * @param factory the view factory 453 * @param context the display context 454 * @param substance the object the field is part of 455 * @param field the field item 456 * @param view the view to build the field for 457 * @param embedded use embbeded editors 458 */ 459 protected static View getPrimitiveFieldPane( 460 ViewFactory factory, 461 DisplayContext context, 462 Object substance, 463 FieldItem field, 464 ObjectView objectView, 465 MemberItemView memberView, 466 boolean embedded) 467 { 468 logger.debug("primitive field : " + substance + "," + field.getName()); 469 470 /* 471 Boolean attrValue = (Boolean)field.getAttribute(GuiAC.BORDER); 472 boolean border = attrValue!=null && attrValue.booleanValue(); 473 */ 474 475 CompositeView container = 476 factory.createCompositeView( 477 "field[" + field.getName() + "]", 478 "Container", 479 new Object[] { new Integer(Constants.HORIZONTAL)}, 480 context); 481 Border border = GuiAC.getBorder(field); 482 if (border != null) { 483 border.setTitle(GuiAC.getLabel(field)); 484 container.setViewBorder(border); 485 } 486 container.setStyle((String) field.getAttribute(GuiAC.STYLE)); 487 Boolean displayLabel = 488 (Boolean) field.getAttribute(GuiAC.DISPLAY_LABEL); 489 boolean useEditor = 490 GuiAC.isEditable(substance, field) 491 && memberView.isEmbeddedEditor(embedded) 492 && !objectView.isReadOnly(); 493 if ((border == null) 494 && (displayLabel == null 495 || (displayLabel != null && displayLabel.booleanValue()))) { 496 container.addView( 497 factory.createView( 498 GuiAC.getLabel(field) + ": ", 499 "Label", 500 context)); 501 } 502 503 FieldEditor editor = null; 504 if (useEditor) { 505 MethodItem setter = field.getSetter(); 506 if (setter != null) { 507 try { 508 editor = 509 getEditorComponent( 510 factory, 511 context, 512 field.getSubstance(substance), 513 setter, 514 0, 515 true, 516 null); 517 context.addEditor(editor); 518 container.addView(editor); 519 } catch (Exception e) { 520 // If the editor failed, we'll try a normal view 521 logger.error("Failed to build editor component for "+ 522 substance+"."+field.getName(),e); 523 } 524 } 525 } 526 if (editor==null) { 527 Object value = field.getThroughAccessor(substance); 528 if (!getViewer(substance, 529 field, 530 value, 531 container, 532 factory, 533 context)) 534 { 535 Enum enum = GuiAC.getEnum(field); 536 if (enum != null) { 537 container.addView( 538 factory.createView( 539 field.getName(), 540 "Enum", 541 new Object[] { value, enum, substance, field }, 542 context)); 543 } else { 544 container.addView( 545 factory.createView( 546 field.getName(), 547 "Field", 548 new Object[] { value, substance, field }, 549 context)); 550 } 551 } 552 553 if (GuiAC.isEditable(substance, field) && !objectView.isReadOnly()) { 554 container.addView( 555 getEditButton(factory, substance, field, context)); 556 } 557 } 558 return container; 559 } 560 561 /** 562 * Build a view containing a label for the name of the field, and 563 * the view of the reference. 564 * 565 * @param factory the view factory 566 * @param context the display context 567 * @param substance the object the field is part of 568 * @param field the field item 569 * @param embedded use embbeded editors 570 */ 571 static protected View getReferenceFieldPane( 572 ViewFactory factory, 573 DisplayContext context, 574 Object substance, 575 FieldItem field, 576 boolean embedded, 577 ObjectView objectView, 578 MemberItemView memberView) 579 { 580 logger.debug("reference field : " + field.getName()); 581 /* 582 Boolean attrValue = (Boolean)field.getAttribute(GuiAC.BORDER); 583 boolean border = attrValue!=null && attrValue.booleanValue(); 584 */ 585 CompositeView container = 586 factory.createCompositeView( 587 "field[" + field.getName() + "]", 588 "Container", 589 new Object[] { new Integer(Constants.HORIZONTAL)}, 590 context); 591 592 Border border = GuiAC.getBorder(field); 593 if (border != null) { 594 border.setTitle(GuiAC.getLabel(field)); 595 container.setViewBorder(border); 596 } 597 598 container.setStyle((String) field.getAttribute(GuiAC.STYLE)); 599 Boolean displayLabel = 600 (Boolean) field.getAttribute(GuiAC.DISPLAY_LABEL); 601 602 if ((border == null) 603 && (displayLabel == null 604 || (displayLabel != null && displayLabel.booleanValue()))) { 605 606 container.addView( 607 factory.createView( 608 GuiAC.getLabel(field) + ": ", 609 "Label", 610 context)); 611 } 612 613 if ((memberView != null && memberView.isEmbedded()) && !embedded) { 614 FieldItem oppositeRole = 615 (FieldItem) field.getAttribute(RttiAC.OPPOSITE_ROLE); 616 if (oppositeRole instanceof CollectionItem) { 617 loggerAssoc.debug("Ignoring collection oppositeRole " + oppositeRole); 618 oppositeRole = null; 619 } 620 Collaboration.get().addAttribute(GuiAC.OPPOSITE_ROLE, oppositeRole); 621 try { 622 logger.debug("embedded view for " + field); 623 container.addView( 624 factory.createObjectView( 625 "embbeded " + field.getName(), 626 field.getThroughAccessor(substance), 627 substance, 628 field, 629 context)); 630 } finally { 631 Collaboration.get().addAttribute(GuiAC.OPPOSITE_ROLE, null); 632 } 633 } else { 634 if (memberView.isEmbeddedEditor(embedded) 635 && GuiAC.isEditable(substance, field) 636 && !objectView.isReadOnly()) 637 { 638 MethodItem setter = field.getSetter(); 639 FieldEditor editor = 640 getEditorComponent( 641 factory, 642 context, 643 field.getSubstance(substance), 644 setter, 645 0, 646 true, 647 null); 648 container.addView(editor); 649 context.addEditor(editor); 650 } else { 651 //Object value = field.getThroughAccessor(substance); 652 //if (!getViewer(substance,field,value,container,factory,context)) { 653 View refView = 654 factory.createView( 655 field.getName(), 656 "Reference", 657 new Object[] { 658 field.getThroughAccessor(substance), 659 field.getSubstance(substance), 660 field.getField()}, 661 context); 662 if (refView instanceof LinkGenerator) 663 ((LinkGenerator)refView).setEnableLinks(objectView.areLinksEnabled()); 664 container.addView(refView); 665 666 if (GuiAC.isEditable(field.getSubstance(substance),field.getField()) 667 && !objectView.isReadOnly()) { 668 container.addView( 669 getEditButton( 670 factory, 671 field.getSubstance(substance), 672 field.getField(), 673 context)); 674 } 675 //} 676 } 677 } 678 return container; 679 } 680 681 /** 682 * Adds choices within a container containing a combobox and sort 683 * them. 684 * 685 * @param choice combo box model to fill 686 * @param type type of objects to fill the model with 687 * @param field associated field item 688 * @param nullAllowed boolean telling wether the add null to themodel 689 * @param nullLabel if nullAllowed==true, the label to use for the null value (if not null) 690 * @param predicate if not null, only add objects which match this 691 * predicate 692 */ 693 static protected void addChoices( 694 ComboBoxModel choice, 695 ClassItem type, 696 Enum enum, 697 Object substance, 698 FieldItem field, 699 boolean nullAllowed, 700 String nullLabel, 701 Predicate predicate) 702 { 703 // use JacObjects.getObjects(type) instead 704 Collection all_objects = null; 705 logger.debug("ObjectChooser.type = " + type 706 + "; predicate=" + predicate 707 + "; field=" + field 708 + "; nullAllowed=" + nullAllowed); 709 if (field != null) { 710 Object fieldChoice = field.getAttribute(GuiAC.FIELD_CHOICE); 711 logger.debug(" fieldChoice = "+fieldChoice); 712 if (fieldChoice instanceof MethodItem) { 713 try { 714 all_objects = 715 (Collection) (((MethodItem) fieldChoice) 716 .invoke(null, ExtArrays.emptyObjectArray)); 717 } catch (Exception e) { 718 e.printStackTrace(); 719 } 720 } else if (fieldChoice instanceof CollectionItem) { 721 all_objects = ((CollectionItem)fieldChoice).getActualCollectionThroughAccessor(substance); 722 } 723 choice.setType(type); 724 } 725 726 if (enum!=null) { 727 Iterator it = enum.getValues().iterator(); 728 while (it.hasNext()) { 729 String str = (String) it.next(); 730 choice.addObject(new Integer(enum.string2int(str)), str); 731 } 732 choice.setType(type); 733 if (nullAllowed) { 734 choice.setNullLabel(nullLabel); 735 choice.addObject(null); 736 } 737 } else { 738 739 if (all_objects == null) { 740 all_objects = ObjectRepository.getObjects(type); 741 choice.setType(type); 742 } 743 if (nullAllowed) { 744 choice.setNullLabel(nullLabel); 745 choice.addObject(null); 746 } 747 748 Iterator i = all_objects.iterator(); 749 while (i.hasNext()) { 750 Object object = i.next(); 751 if (predicate == null || predicate.apply(object)) { 752 choice.addObject(object); 753 } 754 } 755 choice.sort(); 756 } 757 } 758 759 /** 760 * Constructs an edit button for reference views. 761 */ 762 static protected View getEditButton( 763 ViewFactory factory, 764 Object substance, 765 FieldItem field, 766 DisplayContext context) 767 { 768 MethodView methodView = 769 (MethodView) factory.createView( 770 "edit " + field.getName(), 771 "Method", 772 new Object[] { substance, field.getSetter()}, 773 context); 774 methodView.setIcon(ResourceManager.getResource("edit_icon")); 775 methodView.setOnlyIcon(true); 776 return methodView; 777 } 778 779 /** 780 * Builds a view that will display a given collection field of an 781 * object. 782 * 783 * @param factory the view factory to use to build other inner views 784 * @param context the display context 785 * @param substance the object that contains the collection 786 * @param collection the collection to show 787 * @return the associated view 788 * @see TableModel 789 */ 790 static public View getCollectionPane( 791 ViewFactory factory, 792 DisplayContext context, 793 Object substance, 794 ObjectView objectView, 795 CollectionItemView memberView, 796 CollectionItem collection) throws ViewFactory.UnhandledViewTypeException 797 { 798 logger.debug("collection : " + collection.getName()); 799 String label = "collection[" + collection.getName() + "]"; 800 /* 801 View newPane; 802 if (collection.isMap() && collection.getAttribute("Gui.tableView")==null) { 803 newPane = new MapView(parent,this,substance,collection); 804 } else { 805 newPane = new CollectionView(parent,this,substance,collection); 806 } 807 newPane.setName( collection.getName() ); 808 } 809 */ 810 811 CompositeView container = 812 factory.createCompositeView( 813 label, 814 "Container", 815 new Object[] { new Integer(Constants.VERTICAL)}, 816 context); 817 818 Boolean displayLabel = 819 (Boolean) collection.getAttribute(GuiAC.DISPLAY_LABEL); 820 Border border = GuiAC.getBorder(collection); 821 logger.debug(" border="+border); 822 if (displayLabel == null 823 || (displayLabel != null && displayLabel.booleanValue())) { 824 825 if (border != null) { 826 border.setTitle(GuiAC.getLabel(collection)); 827 } else { 828 if (GuiAC.isChoiceView(collection)) { 829 border = new Border(null, Border.LEFT, Border.LINE); 830 } else { 831 border = 832 new Border( 833 GuiAC.getLabel(collection), 834 Border.LEFT, 835 Border.LINE); 836 } 837 } 838 container.setViewBorder(border); 839 } 840 841 container.setStyle((String) collection.getAttribute(GuiAC.STYLE)); 842 843 View view = null; 844 Collaboration.get().addAttribute( 845 GuiAC.OPPOSITE_ROLE, 846 collection.getAttribute(RttiAC.OPPOSITE_ROLE)); 847 GuiAC.pushGraphicContext(collection); 848 try { 849 850 if (memberView.getViewType() != null) { 851 852 view = 853 factory.createView( 854 label, 855 memberView.getViewType(), 856 new Object[] { collection, substance, memberView }, 857 context); 858 container.addView(view); 859 860 } else if (memberView != null && memberView.isEmbedded()) { 861 Collection values = 862 collection.getActualCollectionThroughAccessor(substance); 863 Iterator it = values.iterator(); 864 while (it.hasNext()) { 865 Object value = it.next(); 866 container.addView( 867 factory.createView( 868 "embbeded " + collection.getName(), 869 "Object", 870 new Object[] { value }, 871 context)); 872 } 873 874 } else { 875 if (GuiAC.isTableView(collection)) { 876 877 // TABLE 878 logger.debug(" isTableView"); 879 ExtendedTableModel model = 880 new TableModel( 881 collection, 882 substance, 883 objectView != null 884 ? objectView.getName() 885 : GuiAC.DEFAULT_VIEW, 886 factory); 887 888 Collection filteredColumns = 889 (Collection)collection.getAttribute(GuiAC.FILTERED_COLUMNS); 890 if (filteredColumns!=null) { 891 model = new TableFilter(model,filteredColumns); 892 } 893 894 model = new TableSorter(model); 895 896 view = 897 factory.createView( 898 label, 899 "Table", 900 new Object[] { 901 collection, 902 substance, 903 model, 904 memberView }, 905 context); 906 907 } else if (GuiAC.isChoiceView(collection)) { 908 909 // CHOICE VIEW 910 logger.debug(" isChoiView"); 911 ComboBoxModel model = 912 new ComboBoxModel(collection, substance); 913 view = 914 factory.createView( 915 label, 916 "ChoiceCollection", 917 new Object[] { 918 collection, 919 substance, 920 model, 921 memberView }, 922 context); 923 924 } else { 925 926 // LIST 927 logger.debug(" isListView"); 928 ListModel model = new ListModel(collection, substance); 929 view = 930 factory.createView( 931 label, 932 "List", 933 new Object[] { 934 collection, 935 substance, 936 model, 937 memberView }, 938 context); 939 } 940 941 Integer height = 942 (Integer) collection.getAttribute(GuiAC.VIEW_HEIGHT); 943 Integer width = 944 (Integer) collection.getAttribute(GuiAC.VIEW_WIDTH); 945 if (height == null) 946 height = new Integer(70); 947 if (width == null) 948 width = new Integer(500); 949 view.setWidth(width.intValue()); 950 view.setHeight(height.intValue()); 951 container.addView(view); 952 } 953 } finally { 954 Collaboration.get().addAttribute(GuiAC.OPPOSITE_ROLE, null); 955 GuiAC.popGraphicContext(); 956 } 957 958 return container; 959 } 960 961 /** 962 * Gets a composite panel containing a set of methods that are held 963 * by the substance object. */ 964 965 static protected CompositeView getMethodsPane( 966 ViewFactory factory, 967 DisplayContext context, 968 Object substance, 969 Collection methods, 970 String category, 971 ObjectView objectView) throws ViewFactory.UnhandledViewTypeException 972 { 973 CompositeView methodpane = 974 factory.createCompositeView( 975 "methods", 976 "Container", 977 new Object[] { new Integer(Constants.VERTICAL)}, 978 context); 979 methodpane.setStyle("methods"); 980 981 CompositeView subMP = 982 factory.createCompositeView( 983 "methods0", 984 "Container", 985 new Object[] { new Integer(Constants.HORIZONTAL)}, 986 context); 987 988 Iterator it = methods.iterator(); 989 int i = 0; 990 int nbMethods = 0; 991 992 while (it.hasNext()) { 993 994 MethodItem curmeth = (MethodItem) it.next(); 995 MemberItemView memberView = 996 GuiAC.getView(curmeth, objectView.getName()); 997 998 logger.debug("handling method " + curmeth); 999 1000 if (i == 3) { 1001 methodpane.addView(subMP); 1002 subMP = 1003 factory.createCompositeView( 1004 "methods" + i, 1005 "Container", 1006 new Object[] { new Integer(Constants.HORIZONTAL)}, 1007 context); 1008 i = 0; 1009 } 1010 1011 if (curmeth == null) 1012 continue; 1013 1014 if (!GuiAC.isMemberInCategory(curmeth, category)) { 1015 logger.debug("category, skipping " + curmeth); 1016 continue; 1017 } 1018 1019 if (!GuiAC.isVisible(substance, curmeth)) { 1020 logger.debug("invisible, skipping " + curmeth); 1021 continue; 1022 } 1023 1024 subMP.addView( 1025 getMethodView( 1026 curmeth, 1027 substance, 1028 context, 1029 factory, 1030 memberView)); 1031 i++; 1032 nbMethods++; 1033 } 1034 1035 if (nbMethods > 0) { 1036 methodpane.addView(subMP); 1037 return methodpane; 1038 } else { 1039 return null; 1040 } 1041 } 1042 1043 /** 1044 * Build view for a method 1045 * @param method the method item to build a view for 1046 * @param substance the object the method shall be invoked on 1047 * @param context display context 1048 * @param factory a view factory 1049 * @return a MethodView 1050 */ 1051 public static MethodView getMethodView( 1052 AbstractMethodItem method, 1053 Object substance, 1054 DisplayContext context, 1055 ViewFactory factory, 1056 MemberItemView memberView) 1057 { 1058 String text = GuiAC.getLabel(method); 1059 if (method.getParameterTypes().length > 0) { 1060 text += "..."; 1061 } 1062 MethodView methodView = null; 1063 if (memberView != null && memberView.isEmbedded()) { 1064 EditorContainer inputView = 1065 (EditorContainer) factory.createView( 1066 "parameters[" + method.getName() + "]", 1067 "InputParameters", 1068 new Object[] { method, substance, null }, 1069 context); 1070 methodView = 1071 (MethodView) factory.createView( 1072 text, 1073 "EmbeddedMethod", 1074 new Object[] { substance, method, inputView }, 1075 context); 1076 } else { 1077 methodView = 1078 (MethodView) factory.createView( 1079 text, 1080 "Method", 1081 new Object[] { substance, method }, 1082 context); 1083 } 1084 methodView.setIcon(GuiAC.getIcon(method)); 1085 return methodView; 1086 } 1087 1088 /** 1089 * <p>Create a view containing editor components for the parameters of 1090 * a method.</p> 1091 * 1092 * <p>Parameters of type 1093 * <code>org.objectweb.jac.aspects.gui.DisplayContext</code> are 1094 * not displayed.</p> 1095 * 1096 * <p>If method is a MixinMethodItem, the first parameter is at 1097 * index 1 of the parameters array.</p> 1098 * 1099 * @param factory the ViewFactory 1100 * @param context the DisplayContext 1101 * @param method the method whose parameters you the view of 1102 * @param substance the object on which the method will be 1103 * called. It used to get a default value if the method is a 1104 * setter. 1105 * @param parameters 1106 * @return a CompositeView containing an editor component for each 1107 * parameter of the method. The returned View implements the 1108 * EditorContainer interface 1109 */ 1110 static public View createParameters( 1111 ViewFactory factory, 1112 DisplayContext context, 1113 final AbstractMethodItem method, 1114 Object substance, 1115 Object[] parameters) 1116 { 1117 logger.debug("createParameters(" + method.getLongName() + ")"); 1118 1119 CompositeView panel = 1120 factory.createCompositeView( 1121 method.toString(), 1122 "ParameterContainer", 1123 new Object[] { Boolean.FALSE }, 1124 context); 1125 1126 Class[] paramTypes = method.getParameterTypes(); 1127 String[] paramNames = GuiAC.getParameterNames(method); 1128 1129 for (int i=0; i<paramTypes.length; i++) 1130 { 1131 1132 if (paramTypes[i]==DisplayContext.class) 1133 continue; 1134 1135 String paramName = null; 1136 if (paramNames != null && paramNames.length>i && paramNames[i] != null) { 1137 paramName = paramNames[i]; 1138 } else { 1139 paramName = "arg" + i + " (" + paramTypes[i] + ")"; 1140 } 1141 1142 CompositeView container = 1143 factory.createCompositeView( 1144 method.toString(), 1145 "Container", 1146 new Object[] { new Integer(Constants.HORIZONTAL)}, 1147 context); 1148 container.addView( 1149 factory.createView( 1150 paramName + " : ", 1151 "Label", 1152 ExtArrays.emptyObjectArray, 1153 context)); 1154 // ((Component)ve).setName( "arg" + i ); 1155 1156 try { 1157 FieldEditor editor = 1158 getEditorComponent( 1159 factory, 1160 context, 1161 substance, 1162 method, 1163 i, 1164 false, 1165 parameters != null ? method.getParameter(parameters,i) : null); 1166 ((EditorContainer) panel).addEditor(editor); 1167 container.addView(editor); 1168 } catch (Exception e) { 1169 logger.error( 1170 "Failed to build editor component for " 1171 + method + "[" + i + "]",e); 1172 } 1173 1174 panel.addView(container); 1175 } 1176 return panel; 1177 } 1178 1179 /** 1180 * Returns a ValueEditor suitable for editing the i-th parameter of 1181 * a method. 1182 * 1183 * @param factory the view factory 1184 * @param substance the substance object 1185 * @param method the method that contains the parameter 1186 * @param i the parameter index 1187 * @param embedded wether the editor is an embedded field 1188 * editor. If true, the component will commit changes when it 1189 * looses the focus (only works for swing). 1190 * @param value the initial edited value. Used only if non null. 1191 */ 1192 public static FieldEditor getEditorComponent( 1193 ViewFactory factory, 1194 DisplayContext context, 1195 Object substance, 1196 AbstractMethodItem method, 1197 int i, 1198 boolean embedded, 1199 Object value) 1200 { 1201 logger.debug("getEditorComponent " + method + "[" + i + "]"); 1202 Class[] paramTypes = method.getParameterTypes(); 1203 ClassRepository cr = ClassRepository.get(); 1204 ClassItem paramType = cr.getClass(paramTypes[i]); 1205 String[] passwordParams = 1206 (String[]) method.getAttribute(GuiAC.PASSWORD_PARAMETERS); 1207 Object[] defaultValues = 1208 (Object[]) method.getAttribute(GuiAC.DEFAULT_VALUES); 1209 FieldItem[] parameterFields = 1210 (FieldItem[]) method.getAttribute(RttiAC.PARAMETERS_FIELDS); 1211 Object[] parameterChoices = 1212 (Object[]) method.getAttribute(GuiAC.PARAMETER_CHOICES); 1213 boolean[] editableChoices = 1214 (boolean[]) method.getAttribute(GuiAC.EDITABLE_CHOICES); 1215 MetaItem[] parametersType = 1216 (MetaItem[]) method.getAttribute(RttiAC.PARAMETER_TYPES); 1217 Enum[] enums = (Enum[]) method.getAttribute(GuiAC.PARAMETER_ENUMS); 1218 CollectionItem[] linkedColls = 1219 (CollectionItem[]) method.getAttribute(GuiAC.LINKED_PARAMETERS); 1220 1221 FieldItem editedField = null; 1222 FieldItem parameterField = null; 1223 1224 Object defaultValue = null; 1225 boolean defaultValueSet = false; 1226 if (defaultValues != null) { 1227 defaultValue = defaultValues[i]; 1228 defaultValueSet = true; 1229 } 1230 if (value != null) { 1231 defaultValue = value; 1232 defaultValueSet = true; 1233 } 1234 Object choiceObject = null; 1235 Object[] choice = null; 1236 Enum enum = null; 1237 boolean editableChoice = false; 1238 // the most specific type of the edited value 1239 MetaItem type = null; 1240 // a stack of type of the edited value (most specific on top) 1241 Stack types = new Stack(); 1242 1243 if (parameterFields != null) { 1244 parameterField = parameterFields[i]; 1245 } 1246 // if it's a set-method, get the default value from the field 1247 // as well as the editableChoice attribute 1248 editedField = ((MethodItem) method).getSetField(); 1249 if (editedField != null) { 1250 editedField = cr.getActualField(substance,editedField); 1251 logger.debug("edited field = " + editedField); 1252 if (substance != null) { 1253 defaultValue = editedField.getThroughAccessor(substance); 1254 defaultValueSet = true; 1255 } 1256 1257 Object[] def_value = 1258 ((Object[]) editedField.getAttribute(GuiAC.DYN_DEFAULT_VALUE)); 1259 if ((!RttiAC.isNullAllowed(editedField)) 1260 && (defaultValue == null) 1261 && (def_value != null)) 1262 defaultValue = 1263 ((MethodItem) def_value[0]).invokeStatic( 1264 new Object[] { editedField, def_value[1] }); 1265 1266 choiceObject = editedField.getAttribute(GuiAC.FIELD_CHOICE); 1267 editableChoice = GuiAC.isEditableChoice(editedField); 1268 enum = (Enum) editedField.getAttribute(GuiAC.FIELD_ENUM); 1269 logger.debug( 1270 "choiceObject = "+ choiceObject 1271 + (editableChoice ? " editable" : "")); 1272 type = RttiAC.getFieldType(editedField,substance); 1273 if (type != null) { 1274 logger.debug("adding rtti type = " + type); 1275 if (!types.contains(type)) 1276 types.add(0, type); 1277 } 1278 if (type == null) 1279 type = editedField.getTypeItem(); 1280 if (editedField.getTypeItem() != null) { 1281 logger.debug("adding type item = " + editedField.getTypeItem()); 1282 if (!types.contains(editedField.getTypeItem())) 1283 types.add(0, editedField.getTypeItem()); 1284 } 1285 } 1286 1287 if (parameterField != null) { 1288 logger.debug("parameter field = " + parameterField); 1289 1290 Object[] def_value = 1291 ((Object[]) parameterField 1292 .getAttribute(GuiAC.DYN_DEFAULT_VALUE)); 1293 if ((!RttiAC.isNullAllowed(parameterField)) 1294 && (defaultValue == null) 1295 && (def_value != null)) 1296 defaultValue = 1297 ((MethodItem) def_value[0]).invokeStatic( 1298 new Object[] { parameterField, def_value[1] }); 1299 1300 choiceObject = parameterField.getAttribute(GuiAC.FIELD_CHOICE); 1301 editableChoice = GuiAC.isEditableChoice(parameterField); 1302 enum = (Enum) parameterField.getAttribute(GuiAC.FIELD_ENUM); 1303 logger.debug("choiceObject = " 1304 + choiceObject 1305 + (editableChoice ? " editable" : "")); 1306 type = RttiAC.getFieldType(parameterField,substance); 1307 if (type != null) { 1308 logger.debug("adding rtti type = " + type); 1309 if (!types.contains(type)) 1310 types.add(0, type); 1311 } 1312 if (type == null) 1313 type = parameterField.getTypeItem(); 1314 if (parameterField.getTypeItem() != null) { 1315 logger.debug("adding type item = " + parameterField.getTypeItem()); 1316 if (!types.contains(parameterField.getTypeItem())) 1317 types.add(0, parameterField.getTypeItem()); 1318 } 1319 } 1320 1321 if (defaultValueSet && defaultValue != null) { 1322 if (type == null) 1323 type = cr.getClass(defaultValue); 1324 if (!types.contains(cr.getClass(defaultValue))) 1325 types.add(0, cr.getClass(defaultValue)); 1326 logger.debug("adding default value type = " 1327 + cr.getClass(defaultValue)); 1328 } 1329 if (parametersType != null) { 1330 if (type == null && parametersType[i] instanceof ClassItem) 1331 type = (ClassItem) parametersType[i]; 1332 if (!types.contains(parametersType[i])) 1333 types.add(0, parametersType[i]); 1334 logger.debug("adding rtti parameter type = " + parametersType[i]); 1335 } 1336 if (type == null) 1337 type = paramType; 1338 if (!types.contains(paramType)) 1339 types.add(0, paramType); 1340 logger.debug("adding parameter type = " 1341 + paramType); 1342 1343 if (parameterField != null) { 1344 choiceObject = parameterField.getAttribute(GuiAC.FIELD_CHOICE); 1345 } 1346 1347 if (enum == null && enums != null) 1348 enum = enums[i]; 1349 1350 logger.debug("types: " + types); 1351 logger.debug("type=" + type); 1352 1353 if (parameterChoices != null) { 1354 choiceObject = parameterChoices[i]; 1355 } 1356 1357 boolean classChoice = false; 1358 if (choiceObject==null) { 1359 choiceObject = type.getAttribute(GuiAC.CLASS_CHOICES); 1360 logger.debug("classChoices="+choiceObject); 1361 classChoice = choiceObject!=null; 1362 } 1363 1364 if (choiceObject != null) { 1365 if (choiceObject instanceof MethodItem) { 1366 MethodItem choiceMethod = (MethodItem) choiceObject; 1367 logger.debug("choiceMethod="+choiceMethod); 1368 try { 1369 if (classChoice) { 1370 choiceObject = 1371 choiceMethod.invokeStatic(new Object[] {type}); 1372 } else { 1373 if (choiceMethod.isStatic()) { 1374 choiceObject = 1375 choiceMethod.invokeStatic( 1376 new Object[] { substance }); 1377 } else { 1378 choiceObject = 1379 choiceMethod.invoke( 1380 substance, 1381 ExtArrays.emptyObjectArray); 1382 } 1383 } 1384 logger.debug("choiceMethod returned "+choiceObject); 1385 } catch (Exception e) { 1386 logger.error( 1387 "Invocation of choice "+choiceMethod+" method failed",e); 1388 } 1389 } 1390 if (choiceObject instanceof Object[]) { 1391 choice = (Object[]) choiceObject; 1392 } else if ( 1393 choiceObject.getClass().isArray() 1394 && choiceObject.getClass().getComponentType().isPrimitive()) { 1395 choice = Classes.convertPrimitiveArray(choiceObject); 1396 } else if (choiceObject instanceof Collection) { 1397 choice = ((Collection) choiceObject).toArray(); 1398 } 1399 } 1400 1401 FieldEditor editor = null; 1402 String editorName = 1403 "editor " + Naming.getName(substance) + "." + 1404 method.getName() + "[" + i + "]"; 1405 1406 boolean nullAllowed = false; 1407 if (editedField == null) { 1408 nullAllowed = RttiAC.isNullAllowedParameter(method, i); 1409 } else { 1410 nullAllowed = RttiAC.isNullAllowed(editedField); 1411 } 1412 1413 if (linkedColls != null && linkedColls[i] != null) { 1414 1415 ComboBoxModel model = new ComboBoxModel(linkedColls[i], substance); 1416 1417 editor = 1418 factory.createEditor( 1419 editorName, 1420 "ObjectChooser", 1421 new Object[] { 1422 substance, 1423 editedField, 1424 model, 1425 Boolean.FALSE }, 1426 context); 1427 1428 } else if (choice != null) { 1429 if (editableChoices != null) { 1430 editableChoice = editableChoices[i]; 1431 } 1432 ComboBoxModel model = new ComboBoxModel(); 1433 for (int j = 0; j < choice.length; j++) { 1434 if (enum != null) 1435 model.addObject( 1436 choice[j], 1437 enum.int2string(((Integer) choice[j]).intValue())); 1438 else 1439 model.addObject(choice[j]); 1440 } 1441 if (nullAllowed) 1442 model.addObject(null); 1443 if (type instanceof ClassItem) 1444 model.setType((ClassItem) type); 1445 model.sort(); 1446 1447 editor = 1448 factory.createEditor( 1449 editorName, 1450 "ObjectChooser", 1451 new Object[] { 1452 substance, 1453 editedField, 1454 model, 1455 ExtBoolean.valueOf(editableChoice)}, 1456 context); 1457 } else if (enum != null) { 1458 ComboBoxModel model = new ComboBoxModel(); 1459 Iterator it = enum.getValues().iterator(); 1460 while (it.hasNext()) { 1461 String str = (String) it.next(); 1462 model.addObject(new Integer(enum.string2int(str)), str); 1463 } 1464 1465 editor = 1466 factory.createEditor( 1467 editorName, 1468 "ObjectChooser", 1469 new Object[] { 1470 substance, 1471 editedField, 1472 model, 1473 Boolean.FALSE }, 1474 context); 1475 1476 } else if ( 1477 !factory.hasViewerFor( 1478 "editor:" + ((MetaItem) types.peek()).getName()) 1479 && (Wrappee.class.isAssignableFrom(paramTypes[i]) 1480 || paramTypes[i] == Object.class)) { 1481 // jac objects 1482 ClassItem collectionType = null; 1483 if (types.size() > 0) 1484 collectionType = (ClassItem) types.peek(); 1485 else 1486 collectionType = paramType; 1487 Predicate predicate = null; 1488 if (method instanceof MethodItem) { 1489 CollectionItem[] collections = 1490 ((MethodItem) method).getAddedCollections(); 1491 if (collections != null && collections.length > 0) { 1492 predicate = 1493 new NotInCollectionPredicate( 1494 (Collection) collections[0].getThroughAccessor( 1495 substance)); 1496 } 1497 } 1498 editor = 1499 createReferenceEditor( 1500 factory, 1501 context, 1502 substance, 1503 editedField, 1504 editorName, 1505 collectionType, 1506 predicate, 1507 nullAllowed,null, 1508 GuiAC.isCreationAllowedParameter(method, i)); 1509 /* 1510 } else if (paramTypes[i].isArray() 1511 || Collection.class.isAssignableFrom(paramTypes[i])) { 1512 */ 1513 // array and collections 1514 // editor = new ArrayEditor(paramTypes[i]); 1515 } else { 1516 1517 boolean isPassword = 1518 passwordParams != null && passwordParams[i].equals("true"); 1519 1520 Vector tried_types = new Vector(); 1521 Stack viewerTypes = new Stack(); 1522 while (!types.empty() && editor == null) { 1523 String typeName = ((MetaItem)types.pop()).getName(); 1524 viewerTypes.add(0, typeName); 1525 typeName = "editor:" + typeName; 1526 tried_types.add(typeName); 1527 logger.debug("Trying " + typeName); 1528 if (factory.hasViewerFor(typeName) && !isPassword) { 1529 logger.debug("Factory has viewer for " + typeName); 1530 editor = 1531 (FieldEditor) factory.createView( 1532 editorName, 1533 typeName, 1534 new Object[] { substance, editedField }, 1535 context); 1536 } 1537 } 1538 if (editor == null) { 1539 if (!isPassword) 1540 logger.error( 1541 "Could not find an editor component for any of the type " 1542 + tried_types); 1543 editor = 1544 factory.createEditor( 1545 editorName, 1546 "PrimitiveTypeEditor", 1547 new Object[] { 1548 substance, 1549 editedField, 1550 ExtBoolean.valueOf(isPassword)}, 1551 context); 1552 } 1553 } 1554 1555 //if( fieldEditor != null && ve!=null ) { 1556 // System.out.println("added focus listener for "+ve); 1557 // System.out.println("--- Listener is: "+fieldEditor); 1558 // ve.getValueComponent().addFocusListener(fieldEditor); 1559 //((Component)ve).addFocusListener(fieldEditor); 1560 // } 1561 1562 if (defaultValueSet) { 1563 logger.debug("setting default value for " 1564 + method.getName() + " : " + defaultValue); 1565 editor.setValue(defaultValue); 1566 } 1567 1568 editor.setEmbedded(embedded); 1569 1570 logger.debug("type = " + type); 1571 logger.debug("types = " + types); 1572 int width = GuiAC.getEditorColumns(type); 1573 if (width != 0) 1574 editor.setWidth(width); 1575 if (parameterField == null) { 1576 parameterField = editedField; 1577 } 1578 if (parameterField != null) { 1579 width = GuiAC.getEditorCols(parameterField); 1580 if (width != 0) 1581 editor.setWidth(width); 1582 } else { 1583 editor.setWidth(15); 1584 } 1585 1586 int height = GuiAC.getEditorRows(type); 1587 if (height != 0) 1588 editor.setHeight(height); 1589 if (parameterField != null) { 1590 height = GuiAC.getEditorRows(parameterField); 1591 if (height != 0) 1592 editor.setHeight(height); 1593 } else { 1594 editor.setHeight(10); 1595 } 1596 1597 int[] cols = GuiAC.getMethodParametersCols(method); 1598 if (cols != null) { 1599 editor.setWidth(cols[i]); 1600 } 1601 int[] rows = GuiAC.getMethodParametersRows(method); 1602 if (rows != null) { 1603 editor.setHeight(rows[i]); 1604 } 1605 1606 logger.debug("editedType = "+type); 1607 if (type instanceof ClassItem) { 1608 editor.setEditedType((ClassItem)type); 1609 } else if (type instanceof VirtualClassItem) { 1610 if (editedField!=null) 1611 editor.setEditedType(editedField.getTypeItem()); 1612 else 1613 editor.setEditedType(paramType); 1614 } 1615 return editor; 1616 1617 } 1618 1619 /** 1620 * Initialize the panels of a customized gui. 1621 * 1622 * @param factory the view factory 1623 * @param context the display context 1624 * @param internalView the CompositeView which holds the panels 1625 * @param customized the CustomizedGUI 1626 * @param panels if not null, overrides the content of panels 1627 * (panelID -> PanelContent) 1628 */ 1629 public static void initCustomized( 1630 ViewFactory factory, 1631 DisplayContext context, 1632 CompositeView internalView, 1633 CustomizedGUI customized, 1634 Map panels) 1635 { 1636 logger.debug("initCustomized..."); 1637 // open the views on the objects in the right subpanes 1638 if (panels == null) 1639 panels = customized.getPaneContents(); 1640 for (Iterator it = panels.keySet().iterator(); it.hasNext();) { 1641 String paneId = (String) it.next(); 1642 PanelContent panel = (PanelContent) panels.get(paneId); 1643 logger.debug("init pane " + paneId + " -> " + panel); 1644 try { 1645 View view = 1646 factory.createView( 1647 paneId, 1648 panel.getType(), 1649 panel.getArgs(), 1650 context); 1651 internalView.addView(view, paneId); 1652 } catch (Exception e) { 1653 logger.error( 1654 "Failed to build content for pane \"" 1655 + paneId + "\"",e); 1656 } 1657 logger.debug("init pane " + paneId + " DONE"); 1658 } 1659 logger.debug("initCustomized DONE"); 1660 } 1661 1662 /** 1663 * Sets a status bar to a customized view. 1664 * 1665 * @param factory the used factory 1666 * @param context the passed context 1667 * @param view the customized that will hold the status bar 1668 * @param statusBar the method item that defines the text to print within the status bar 1669 * @param position the position 1670 * (<code>Constants.TOP||Constants.BOTTOM</code>) */ 1671 1672 public static void setStatusBar( 1673 ViewFactory factory, 1674 DisplayContext context, 1675 CustomizedView view, 1676 MethodItem statusBar, 1677 String position) 1678 { 1679 logger.debug("setStatusbar(" + statusBar + ")"); 1680 StatusView statusView = 1681 (StatusView) factory.createView( 1682 "StatusBar", 1683 "StatusBar", 1684 new Object[] { statusBar }, 1685 context); 1686 view.setStatusBar(statusView, position); 1687 } 1688 1689 /** 1690 * Build the menu bar of a customized gui. 1691 * 1692 * @param factory the view factory 1693 * @param context the display context 1694 * @param view the CustomizedView where to put the menu bar 1695 * @param menuBars the menuBars 1696 */ 1697 public static void setMenuBars( 1698 ViewFactory factory, 1699 DisplayContext context, 1700 CustomizedView view, 1701 Hashtable menuBars) 1702 { 1703 logger.debug("setMenuBars(" + menuBars + ")"); 1704 Menu menus; 1705 Iterator it = menuBars.values().iterator(); 1706 while (it.hasNext()) { 1707 menus = (Menu) it.next(); 1708 MenuView menuBar = 1709 (MenuView) factory.createView("MenuBar", "MenuBar", context); 1710 menuBar.setPosition(menus.getPosition()); 1711 Iterator i = menus.getKeys().iterator(); 1712 while (i.hasNext()) { 1713 String key = (String) i.next(); 1714 logger.debug("createMenu " + key); 1715 Object item = menus.get(key); 1716 if (item instanceof Menu) { 1717 Menu subMenu = (Menu) item; 1718 menuBar.addSubMenu( 1719 key, 1720 subMenu.getIcon(), 1721 createMenu(factory, context, key, subMenu)); 1722 } else { 1723 if (key == null) { 1724 menuBar.addSeparator(); 1725 } else { 1726 Callback callback = (Callback) item; 1727 if (GuiAC.isVisible(callback.getMethod())) { 1728 menuBar.addAction( 1729 key, 1730 callback.getMethod() != null 1731 ? GuiAC.getIcon(callback.getMethod()) 1732 : null, 1733 callback); 1734 } 1735 } 1736 } 1737 } 1738 view.setMenuBar(menuBar, menus.getPosition()); 1739 } 1740 } 1741 1742 /** 1743 * Creates a menu in a a customized gui. 1744 * 1745 * @param factory the view factory 1746 * @param context the display context 1747 * @param content the content of the menu view 1748 */ 1749 1750 public static MenuView createMenu( 1751 ViewFactory factory, 1752 DisplayContext context, 1753 String label, 1754 Menu content) 1755 { 1756 MenuView menu = (MenuView) factory.createView(label, "Menu", context); 1757 Iterator i = content.getKeys().iterator(); 1758 while (i.hasNext()) { 1759 String key = (String) i.next(); 1760 if (key == null) { 1761 menu.addSeparator(); 1762 } else { 1763 Object value = content.get(key); 1764 if (value instanceof Menu) { 1765 // submenu 1766 MenuView subMenu = 1767 createMenu(factory, context, key, (Menu)value); 1768 menu.addSubMenu(key, ((Menu) value).getIcon(), subMenu); 1769 } else { 1770 // action or separator 1771 logger.debug("menu action: " + key + "->" + value); 1772 if (key == null) { 1773 menu.addSeparator(); 1774 } else { 1775 Callback callback = (Callback) value; 1776 if (callback.getMethod() == null 1777 || GuiAC.isVisible(callback.getMethod())) 1778 { 1779 menu.addAction( 1780 key, 1781 GuiAC.getIcon(callback), 1782 callback); 1783 } 1784 } 1785 } 1786 } 1787 } 1788 return menu; 1789 } 1790 1791 /** 1792 * Build the toolbar of a customized gui. 1793 * 1794 * @param factory the view factory 1795 * @param context the display context 1796 * @param view the CustomizedView where to put the menu bar 1797 * @param toolbar the toolbar definition 1798 */ 1799 public static void setToolBar( 1800 ViewFactory factory, 1801 DisplayContext context, 1802 CustomizedView view, 1803 Collection toolbar) 1804 { 1805 logger.debug("setToolbar(" + toolbar + ")"); 1806 MenuView toolbarView = 1807 (MenuView) factory.createView("ToolBar", "ToolBar", context); 1808 Iterator i = toolbar.iterator(); 1809 while (i.hasNext()) { 1810 Callback callback = (Callback) i.next(); 1811 logger.debug("createButton " + callback); 1812 if (callback != null) { 1813 toolbarView.addAction( 1814 GuiAC.getLabel(callback.method), 1815 GuiAC.getIcon(callback.method), 1816 callback); 1817 } else { 1818 toolbarView.addSeparator(); 1819 } 1820 } 1821 view.setToolBar(toolbarView); 1822 } 1823 1824 /** 1825 * Builds a dialog box to enter the parameters of method 1826 * 1827 * @param substance object the method will be invoked on 1828 * @param method the method 1829 * @param parameters an array where to store the value enteres by the user 1830 * @param context a display context 1831 * 1832 * @see #createParameters(ViewFactory,DisplayContext,AbstractMethodItem,Object,Object[]) 1833 */ 1834 public static DialogView createInputDialog( 1835 Object substance, 1836 AbstractMethodItem method, 1837 Object[] parameters, 1838 DisplayContext context) 1839 { 1840 ViewFactory factory = context.getDisplay().getFactory(); 1841 EditorContainer inputView = 1842 (EditorContainer) factory.createView( 1843 "parameters", 1844 "InputParameters", 1845 new Object[] { method, substance, parameters }, 1846 context); 1847 String description = (String) method.getAttribute(GuiAC.DESCRIPTION); 1848 String title = GuiAC.getLabel(method); 1849 DialogView dialog = 1850 (DialogView) factory.createView( 1851 method.getName(), 1852 "Dialog", 1853 new Object[] { inputView, null, title, description }, 1854 context); 1855 dialog.setLabel(GuiAC.getLabel(method)); 1856 return dialog; 1857 } 1858 1859 /** 1860 * A generic view builder for a reference editor. Returns a combox 1861 * box or a text input depending on the field's configuration 1862 * 1863 * @param factory 1864 * @param context 1865 * @param substance the object holding the field 1866 * @param field the field to build an editor for (may be null) 1867 * @param editorName the name of the editor to build 1868 * @param type the type of the objects to choose from 1869 * @param predicate a predicate used to filter proposed objects in 1870 * the case of a combobox. 1871 * @param nullAllowed wether the user is authorised to select the null value 1872 * @param isCreationAllowed wether the user is authorised to create 1873 * new instances of type 1874 * 1875 * @see org.objectweb.jac.aspects.gui.ClassAppearenceGuiConf#selectWithIndexedField(ClassItem,CollectionItem,String) 1876 */ 1877 public static FieldEditor createReferenceEditor( 1878 ViewFactory factory, 1879 DisplayContext context, 1880 Object substance, 1881 FieldItem field, 1882 String editorName, 1883 ClassItem type, 1884 Predicate predicate, 1885 boolean nullAllowed, 1886 String nullLabel, 1887 boolean isCreationAllowed) 1888 { 1889 logger.debug("createReferenceEditor isCreationAllowed="+isCreationAllowed); 1890 CollectionItem index = 1891 (CollectionItem) type.getAttribute(GuiAC.INDEXED_FIELD_SELECTOR); 1892 if (index != null) { 1893 return factory.createEditor( 1894 editorName, 1895 "IndexSelector", 1896 new Object[] { 1897 substance, 1898 field, 1899 index, 1900 GuiAC.getRepository(type), 1901 ExtBoolean.valueOf(isCreationAllowed), 1902 type.getAttribute(GuiAC.INDEX_NOT_FOUND_HANDLER)}, 1903 context); 1904 } else { 1905 ComboBoxModel model = new ComboBoxModel(); 1906 addChoices(model, type, null, substance, field, 1907 nullAllowed, nullLabel, predicate); 1908 return factory.createEditor( 1909 editorName, 1910 "ObjectChooser", 1911 new Object[] { 1912 substance, 1913 field, 1914 model, 1915 ExtBoolean.valueOf(isCreationAllowed)}, 1916 context); 1917 } 1918 } 1919 1920 public static FieldEditor createEnumEditor( 1921 ViewFactory factory, 1922 DisplayContext context, 1923 Object substance, 1924 FieldItem field, 1925 String editorName, 1926 Enum enum, 1927 boolean nullAllowed, 1928 String nullLabel) 1929 { 1930 ComboBoxModel model = new ComboBoxModel(); 1931 ClassItem type = ClassRepository.get().getClass("java.lang.Integer"); 1932 addChoices(model, type, enum, substance, field, 1933 nullAllowed, nullLabel, null); 1934 return factory.createEditor( 1935 editorName, 1936 "ObjectChooser", 1937 new Object[] { 1938 substance, 1939 field, 1940 model, 1941 Boolean.FALSE}, 1942 context); 1943 } 1944 }