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

Christopher Brooks cxh at eecs.berkeley.edu
Tue Apr 18 07:30:55 PDT 2006

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.
    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.
    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