Python evangelists unite!

James_Althoff at i2.com James_Althoff at i2.com
Wed Dec 5 23:10:08 CET 2001


Peter Milliken wrote:
>Sorry Jim, you are one up on me here, I have never had to face this
>situation. Thanks for the tip. Could you provide a real example of where
you
>might want this? (if it isn't too long to give! :-)). You have made me
>curious.

Sure thing.

Java/Swing is a large and sophisticated GUI framework (written in Java --
we access it via Jython).  There is a superclass JComponent that defines a
large number of fields and methods that are inherited by most other GUI
components in the framework.  We have found several examples where you want
to mark some of your components in order to give them special treatment.

Here's one.  For the ui of an application we want to be able to mark one or
more of the many buttons (or other controls) that might appear in a given
panel as being "emphasized".  The emphasized controls are what the user
would normally click most of the time and we want these to be highlighted
in some prescribed way (according to our corporate guidelines for UI look
and feel).  Swing is designed in a flexible way that lets you easily change
the look of a component.  So it is easy for us to go to that part of the
code and change the drawing algorithm to suit our needs.  But *only* if we
know *which* components need to be drawn with emphasis.  So we need to be
able to mark the emphasized controls in some fashion.  One option is to
subclass the controls to add such an attribute.  However, we can't subclass
JComponent because it is the superclass of all the other controls.  And we
don't want to subclass each of the other controls because there are *many*
of them.  And, in any case, the added attribute would not be generic to all
of them, and we would have to maintain lots of extra classes, etc.  There
are a lot of problems with this approach.  Another approach is to maintain
some kind of list of the emphasized controls.  But this is nasty because
then you need to create a globally defined list (because it is accessed all
over the application) -- which is rarely a good idea.  The global list, for
one thing, causes garbage collection problems because it has extra
references to the emphasized controls.  So then you need to add lots of
extra code to try to manage the extra references.  Or you need to use
advanced techniques like weak references.  Again, it is a mess.  The *easy*
and *straightforward* solution is just to add an "emphasized" attribute to
each component *instance* that is to be emphasized.  The drawing code can
test for the attribute.  If the attribute exists, then the code draws the
control in the emphasized way.  If not, it draws the control in the usual
way.  The Swing designers -- not knowing our application, of course -- did
not include an "isEmphasized" property in JComponent.  And Java doesn't
allow one to add instance-specific attributes.  But the Swing designers did
realize that people would need to do this kind of thing so they included a
catchall hashtable in JComponent that clients can use to add
(putClientProperty) and read (getClientProperty) "instance-specific"
attributes.

Generally, when you deal with user interface widgets (in a large GUI
framework) a lot, you tend to see lots of cases where instance-specific
attributes (both fields and methods) come in handy.

Jim


============================================


<James_Althoff at i2.com> wrote in message
> Peter Milliken wrote:
> >There is no real justification that works for these "features" of
python -
>
> OTOH, there *are* plenty of good *reasons* for them.
>
> Consider "adding attributes to instances".  Languages that don't support
> this feature directly require some kind of a workaround since this is
> something that one simply needs to do from time to time.  A typical
> workaround is to define, as part of a class's definition, a catch-all
> property whose value is a hashtable.  Clients add "instance-specific"
> attributes to a given instance "on the fly" by adding name-value pairs to
> the instance's hashtable.  Java/Swing's JComponent (with its
> putClientProperty and getClientProperty methods) is a good example of
this
> type of workaround.
>
> Jim





More information about the Python-list mailing list