Re: Swing uses bad features
"Oliver Wong" <owong@castortech.com> wrote in message
news:bz1hg.32139$JX1.2993@edtnps82...
"Andrey Kuznetsov" <spam0@imagero.com.invalid> wrote in message
news:e62504$k91$1@online.de...
One place that this causes problems is in a composite component.
Suppose my subclass of JPanel creates 5 other widgets.
Now suppose that I want to reset the background of all of these
components when the user invokes my setBackground() method.
So in my setBackground() i do this:
w1.setBackground(color);
w2.setBackground(color);
etc.
But my setBackground() method gets called by JPanel's
constructor BEFORE my constructor has created any of these widgets!
if you want your 5 widgets to have same background as JPanel,
then set their background to null (for AWT) or make them not opaque (for
swing).
Otherwise in setBackground check if your widgets are not null.
What if he wants the background of his subclass to be transparent, but
the 5 widgets to be opaque?
E.g., he has a widget shaped like:
---- ----
| | | |
| |-----| |
| |
----| |----
| |
----| |----
| |
| |-----| |
| | | |
---- ----
- Oliver
Yes, I know how to solve the background problem using
these (and other) solutions. However, Andrey has missed
the point. The point is that I do not think any of MY
non-static public methods should be invoked before
MY constructor has been completely executed.
My setValues() method (or setBackground) should not
have to keep checking to see if some variable is null,
and ignore the request if it is. What happens if null is
a legitimate value? So the app sets it to null, and then
it can never be reset again, since I ignore the call
if it is null!
For example, here's one that took me quite a while to
figure out what was wrong. I subclasses JLabel to create
a label that has multi-line capability when it is passed
a String with embedded newlines (not HTML). It
just prepends "<HTML>", replaces all newlines
with "<BR>", and appends "</HTML>".
A snippet of the original:
public class JMultiLineLabel extends JLabel
{
private String requested_text = null;
private String converted_text = null;
public JMultiLineLabel(String text, Icon icon, int horizontalAlignment) {
super( text, icon, horizontalAlignment );
}
public void setText( String text ) {
requested_text = text;
converted_text = checkText(text);
super.setText( converted_text );
}
private void checkText( String text ) {
/* Code to convert 'text' to HTML */
...
}
}
The above does not work - the text is always null.
The reason is in the order in which calls are made:
1) in my constructor, super() is called.
2) super() invokes setText(), which executes my setText().
3) my setText() converts the input text into HTML
and stores it in converted_text.
4) The rest of my constructor is then invoked. It looks like
there no other statements there, but in reality, this is when
the instance variables are initialized - AFTER super()
is called, not before. So requested_text and
converted_text are set to null.
Well, I COULD call setText() in MY constructor, but that
does the same work again to convert to HTML that was
already done once, then discarded. Why do it twice?
The solution was to declare the private variables
without explicitly setting them to null:
private String converted_text;
However, if I wanted to do something with converted_text
in the body of my constructor, the compiler then complains that
I am using a uninitialized variable.
--
Fred L. Kleinschmidt
Boeing Associate Technical Fellow
Technical Architect, Software Reuse Project