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

Christopher Brooks cxh at eecs.berkeley.edu
Tue Apr 18 15:31:05 PDT 2006

Hi Matthew,
Thanks for the explanation, that helps quite a bit.

In some ways, the "Ptolemy Way" to remap icons would be to use the
MoML filter mechanism or to change the *Icon.xml file.

I think we could make Edward's solution work by having the 
BatikEditorIcon class do the lookup of the LSID.

What would be a good name for the EditorIcon class that does this?
My understanding is that Ptolemy has some support SVG, so
SVGEditorIcon is out.  BatikEditorIcon has its appeal but
seems too tightly associated with Batik.
How about LSIDEditorIcon?

We could easily add a filter that would insert LSIDEditorIcon
for all Directors and CompositeEntities.  This would also
increase the moml file size.

Edward is offsite this week, let's see what he has to say.




    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:
    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 
     > 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  
    > ComponentEntityConfig.addSVGIconTo(this);
    > 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
    > EditorIcon.
    > 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
    > ptolemy.actor.lib.security.KeyToken. 
    > 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.
    > _Christopher
    > --------
    >     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 woul
    >     >be present for all NamedObjs.  I think it would be better for Direct
    >     >and ComponentEntity to have a setter that sets a class on which we c
    >     >call an addIcon().  Yes, this is a little bit of code duplication, b
    >     >it is not horrible.  Perhaps we could have Director and
    >     >ComponentEntity implement a IconableFactory(?) interface that just h
    >     >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 co
    >     >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
    > http://mercury.nceas.ucsb.edu/ecoinformatics/mailman/listinfo/kepler-dev

More information about the Kepler-dev mailing list