Name: krT82822 Date: 08/17/99
The specification for PropertyEditor.getJavaInitializationString()
does not specify which exceptions (if any) may be thrown by the
code fragment it generates.
For example, a URLEditor class might generate the following code
fragment:
new java.net.URL("http://java.sun.com")
This expression may throw a MalformedURLException (It won't in this
case because "http://java.sun.com" is properly formed, but the
compiler doesn't know that). If this code were compiled, the compiler
would probably complain that you need an exception handler.
I think this issue needs an official ruling, which should be added
to a future revision of the Beans spec. The following questions need
to be answered:
1 - Is getJavaInitializationString() permitted to return code
fragments which may throw checked exceptions?
2 - How can a JavaBeans builder tool determine that the code fragment
might throw an exception? Which exceptions?
3 - What are a JavaBeans builder tool's responsibilities in regards
to handling exceptions in code that it generates?
(Review ID: 94040)
======================================================================
Comments from a Licensee:
PropertyEditors should not have any hidden state and consist of fully qualified class names in the getJavaInitializationString (ie., java.awt.Color(100,100,100)).
Another comment with some brainstorming on design:
One thing that has always caused us problems is
getJavaInitializationString() on java.beans.PropertyEditor, and also how to
work out the changes to a customized JavaBean. The problem with the
getJavaInitializationString() is that it often means you get very
convoluted constructors being created so that all the different flavors of
the JavaBean can be created with a single method call. An example of this
is GridBagConstraints or TitledBorder.
Rather than have everything combined into a single string, what about an
approach where the property editor could return a sequence of statements
that can be used to construct the JavaBean. For example, suppose a
TitledBorder was set with a color and a string, the could right now must
use the constructor that takes color, which also requires the other
arguments so the code is
button.setBorder(new
javax.swing.border.TitledBorder(null,"Title",javax.swing.border.TitlledBorder.LEADING,javax.swing.border.TitledBorder.TOP,null,java.awt.Color.red));
If you were coding this by hand it might instead read
javax.swing.border.TitledBorder border = new javax.swing.TitledBorder
("Title");
border.setTitleColor(java.awt.Color.red);
button.setBorder(border);
Not only is this more concise it is actually the more correc behavior,
because the only non-default values specified are the title and the color.
In the initString that uses the full constructor with 5 arguments, only two
of which is really cares about, it has to supply values to the other 3
arguments. These are now explicitly set and are not default values, so if
the TitledBorder class ever changed its default values the behavior of the
two pieces of code is not the same.
To implement the code that uses an intermediate field and a constructor and
a set method the java.beans.PropertyEditor specification could be changed
to return an list of strings. These would be the two statements
new javax.swing.TitledBorder("Title")
setTitleColor(java.awt.Color.red);
The builder tool that is generating the code is responsible for creating
setting the JavaBean's title has to declare the javax.swing.TitledBorder
field and allocate it with a field name, as it is the only thing that knows
what field name to use. One problem however is that the field really needs
to be declared as javax.swing.TitledBorder so the
setTitleColor(java.awt.Color.red) can be sent to it, something that can't
be worked out from the border property itself because this is typed to the
interface. The type of the field could be returned, e.g.
javax.swing.TitledBorder, or it could be worked out by the builder because
it will have the instance from the getValue() method on the propertyEditor.
new javax.swing.TitledBorder("Title")
setTitleColor(java.awt.Color.red);
The next problem is how to return these from the java.beans.PropertyEditor
without adding new methods to the interface that would be a breaking API
change. There are two ways for this, one is to add the method to
java.beans.PropertyEditorSupport because a lot of people subclass this,
such as
public String[] getJavaInitializationStatements(){
return null;
}
and the border editor could return an array of strings for the statements.
Alternatively the existing java.beans.PropertyEditor interface could be
adapted to return an array of strings somehow. One thought would be that
if getJavaInitializationString() return strings that were surrounded by {}
statements these represented strings, e.g.
public String getJavaInitializationString(){
return "{new javax.swing.TitledBorder("Title")" +
System.getProperty("line.Separator") + "setTitleColor(java.awt.Color.red)}"
}
The builder code that got the string could parse the string and see the
leading { indicating that this was a set of statements, and then break the
string apart where it is delimited by lineSeparators.
Neither of these solutions seem perfect to me, but I wanted to run them
past you to see what you thought. Is this problem with
getJavaInitializationString() something that other folks have raised as an
issue, and do you think there is any runway at all to change the
specification in a non-breaking manner.
###@###.### 2003-03-19