[kepler-dev] Kepler specific Director and ComponentEntity classes and _addIcon()

Edward A. Lee eal at eecs.berkeley.edu
Tue Apr 18 17:50:55 PDT 2006

A simple workaround that would not require having the icon
information in each model's moml file would be to create
a moml class somewhere, and instantiate that in the library.

A better alternative would be to make the current icon
mechanism smarter.  Currently, vergil looks for a particular
file named FooIcon.xml in the same directory as actor and/or
director, and if it finds it, uses that to define the icon.
We could make where to look for this icon something controlled
by the configuration. Then kepler could simply put its
icon definitions, each of which instantiates a subclass
of EditorIcon, in some other directory tree.  Your subclass
of EditorIcon could look wherever you want for the icon
definition, including in a centralized system.

This would deal with the legacy model problem and the problem
of bloating the moml files.


At 09:47 AM 4/18/2006, Matthew Brooke wrote:

>Hi Christopher/Edward -
>A couple of thoughts and some additional info:
> > Also, this means that every Director and ComponentEntity would
> > have to have a BatikEditorIcon attribute in the MoML file.
>We are specifically trying not to include icon descriptions or 
>assignments in the MOML files (or in *Icon.xml files, or hard-coded 
>in java), since it presents a maintenance problem for us (if/when 
>icon assignments change, older models will still show the old 
>assignments). This obviously becomes a larger and larger problem as 
>models proliferate.
>We therefore have all our icon assignments in 2 text files - one has 
>icons assigned by classname, and the other assigned by LSID. When 
>Director or ComponentEntity make the call to:
>  ComponentEntityConfig.addSVGIconTo(this);
>the method does a lookup to try to match the specific subclass (ie 
>the actor or director) by LSID, and then by classname. It then sets 
>a ConfigurableAttribute (called "_svgIcon") on the actor/director, 
>which is subsequently used by the Batik rendering system. (We don't 
>change the existing "_iconDescription" attributes, so these are 
>still present as a"fallback" in case anything goes wrong with the assignments.)
>Having this centralized system is important to us, because it 
>provides a level of decoupling between the models and their visual 
>representations - we can make changes to icon assignments, and even 
>completely change out *all* the icons at once if needed, and thus 
>"re-skin" workflows entirely.
> > 4) My previous idea, where we have some code that sets the Iconable
> > class that gets called.  This results in one method being
> > added to Directory and ComponentEntity.
>Cool idea, but we'd still need to introduce an "Iconable" interface 
>into ptii (maybe I'm just missing the point ;-).  To be completely 
>Kepler agnostic, we'd have to use your reflection solution, I think?
>Just some extra stuff to add to the mix...
>Matthew Brooke, Ph.D.
>Marine Sciences Research Building, Room #3407
>University of California
>Santa Barbara, CA  93106-6150
>ph: (805) 893-7108   fx: 805-893-8062
>brooke at nceas.ucsb.edu
>Christopher Brooks wrote:
>>Interesting idea.  We could create a subclass of EditorIcon called
>>BatikEditorIcon that would do this.
>>However, how would we handle changing the icons of preexisting models?
>>I suppose we could use the MoMLFilter.  This would slow down the Kepler
>>a little, but would not be noticable.
>>Also, this means that every Director and ComponentEntity would have to
>>have a BatikEditorIcon attribute in the MoML file. This will increase
>>model file size a certain amount, say 10%?
>>Besides my proposal below, an alternative that is more in keeping with
>>_iconDescription would be to either modify _iconDescription so it
>>calls the addSVGIcon method or add a static text valued attribute that
>>named the class that was to be called.  I think this would be
>>definitely pollute Director and ComponentEntity with more UI code, but
>>it would also be more lightweight (smaller MoML files).
>>We really need to do something, having separate copies of these files
>>is not maintainable.  I keep fixing problems in Ptolemy and then
>>I or someone else has to update the copies in Kepler.
>>To recap, I see several solutions
>>1) Do nothing - we keep updating these files by hand
>>This is not maintainable.
>>2) Hack in Kepler specific code that calls ComponentEntityConfig
>>I have this implemented in my tree, there is a static initializer
>>that uses reflection to see if ComponentEntityConfig exists and if 
>>it does then each _addIcon() method calls
>>The problem here is that it is somewhat hardwired and ugly.
>>3) My new idea, which would be to somehow modify _iconDescription so
>>that we can invoke a method that creates the icon.  We could either
>>have another attribute, say _iconFactory or we could add a field It
>>would be nice to be able to change the icon once for all Directors and
>>once for all ComponentEntities, so I'd like to create a static method
>>that allows the user to override what text _addIcon attaches.  Perhaps
>>we could attach the BatikEditorIcon here?  Or, _iconDescription could
>>take a class name and method name to be invoked somehow.  This has the
>>advantage of being done once each for Director and ComponentEntity.
>>4) My previous idea, where we have some code that sets the Iconable
>>class that gets called.  This results in one method being
>>added to Directory and ComponentEntity.
>>5) Your idea of using EditorIcon here.
>>This would bulk up the Kepler models a little, say 10%?
>>Also, current models would need a filter.
>>I'm still feeling that I'd prefer to see #4, adding setIcon().
>>What do you think?  I agree that #4 is not perfect but it seems like
>>less work and not much uglification of the UI.  At least I'm staying
>>out of NamedObj :-)
>>My goal here is to help the Kepler folks with some UI problems.  In my
>>mind, it should not be necessary to override Ptolemy classes, it 
>>should be possible to extend classes or use attributes like
>>A good example of this is that for the DBConnectionToken class it was
>>not necessary to override ptolemy.data.type.BaseType, instead I 
>>used an inner class like what we do for
>>If a Ptolemy class is being overridden with a copy of a class, it is
>>either a bug in Ptolemy or a bug in Kepler and it should be fixed
>>so as to avoid problems.
>>     There is no need to modify any Java class to change the icon...
>>     Any attribute (including directors) that contains an instance of
>>     EditorIcon or any subclass of EditorIcon will defer to that class
>>     to render the icon.
>>     So why can't the Kepler configuration just include such an
>>     attribute in every director in the director library?
>>     We have tried to keep the support in the kernel for visual rendering
>>     to an absolute minimum... At most some text-valued attributes,
>>     like _iconDescription. In retrospect, even this was probably a
>>     mistake.  Icons should be controlled by attributes contained
>>     by the object being represented by the icon.
>>     Edward
>>     At 09:21 PM 4/17/2006, Christopher Brooks wrote:
>>     >Hi Edward,
>>     >
>>     >I'm looking at folding in the Kepler copies of Director
>>     >and ComponentEntity.  The reason to fold these in is
>>     >to avoid code duplication and reduce maintenance.
>>     >
>>     >Both of these classes have _addIcon methods like:
>>     >
>>     >     private void _addIcon() {
>>     >
>>     >       //simple Icon:
>>     >       _attachText("_iconDescription", "<svg>\n"
>>     >                   + "<rect x=\"-30\" y=\"-20\" width=\"60\" "
>>     >                   + "height=\"40\" style=\"fill:white\"/>\n"
>>     >                   + "<polygon points=\"-20,-10 20,0 -20,10\" "
>>     >                   + "style=\"fill:blue\"/>\n" + "</svg>\n");
>>     >
>>     >       try {
>>     >         ComponentEntityConfig.addSVGIconTo(this);
>>     >       } catch (Exception ex) {
>>     >         //ignore exceptions - they just mean that the
>>     >         //default icon will be used, as defined above
>>     >       }
>>     >     }
>>     >
>>     >In this case,
>>     >         ComponentEntityConfig.addSVGIconTo(this);
>>     >is a Kepler static method that takes a NamedObj as an argument
>>     >and adds an SVG icon.  So, we need some way for Kepler
>>     >to override the icons without subclassing Director.  We
>>     >can't subclass Director here because SDFDirector etc all
>>     >extend Director and they would not extend our new class that
>>     >had the custom Kepler icons.
>>     >
>>     >I could hack some Kepler specific hack that used reflection to look
>>     >for a specific class that added the icon, but I think it would be
>>     >better to add methods that named a class that on which we invoked a
>>     >method that would add the Icon.
>>     >
>>     >Unfortunately, it looks like this would go in NamedObj and thus would
>>     >be present for all NamedObjs.  I think it would be better for Director
>>     >and ComponentEntity to have a setter that sets a class on which we can
>>     >call an addIcon().  Yes, this is a little bit of code duplication, but
>>     >it is not horrible.  Perhaps we could have Director and
>>     >ComponentEntity implement a IconableFactory(?) interface that just has
>>     >the setIconable method.
>>     >
>>     >
>>     >Director and ComponentEntity would both get
>>     >     setIconable(Iconable iconable) {
>>     >         _iconable = iconable
>>     >     }
>>     >     private static Iconable _iconable;
>>     >
>>     >     private void _addIcon() {
>>     >         _attachText("...");
>>     >         if (_iconable != null) {
>>     >             try {
>>     >                 _iconable.addIcon(this)
>>     >             } catch (Exception ex) {
>>     >                 //ignore exceptions - they just mean that the
>>     >                 //default icon will be used, as defined above
>>     >             }
>>     >     }
>>     >
>>     >ComponentEntityConfig would implement Iconable and have
>>     >     public static addIcon(NamedObj) {
>>     >         ....
>>     >     }
>>     >The KeplerInitiailizer would call setIconable() for
>>     >Director and ComponentEntity and set it to ComponentEntityConfig.
>>     >
>>     >Whattya think?  Do you have any ideas?
>>     >
>>     >Director and ComponentEntity should not really have icon specific code
>>     >in them, but they already have _attachText() calls.
>>     >
>>     >_Christopher
>>     ------------
>>     Edward A. Lee
>>     Professor, Chair of the EE Division, Associate Chair of EECS
>>     231 Cory Hall, UC Berkeley, Berkeley, CA 94720-1770
>>     phone: 510-642-0253 or 510-642-0455, fax: 510-642-2845
>>     eal at eecs.Berkeley.EDU, http://ptolemy.eecs.berkeley.edu/~eal
>>Kepler-dev mailing list
>>Kepler-dev at ecoinformatics.org
>Edward A. Lee
>Professor, Chair of the EE Division, Associate Chair of EECS
>231 Cory Hall, UC Berkeley, Berkeley, CA 94720-1770
>phone: 510-642-0253 or 510-642-0455, fax: 510-642-2845
>eal at eecs.Berkeley.EDU, http://ptolemy.eecs.berkeley.edu/~eal

More information about the Kepler-dev mailing list