IBM® WebSphere® Studio Application Developer (hereafter called Application Developer) lets you visually edit Java™ files that contain JavaBeans components. To use the editor, you click on the Java file you wish to edit and select Open With => Visual Editor from the pop-up menu. The Java file is the only resource that is persisted in the Application Developer workbench, so all of the information about the Java beans, their initial properties, and their relationships, is ascertained by parsing the source statements and recognizing coding patterns. After analyzing the source, the Visual Editor creates an internal model that it uses to build the Java beans shown on the visual canvas and in the Java Beans tree view. When you modify the source code while the Visual Editor is open, it analyzes the change and determines whether it affects the model. If so, then it updates the model to show the change, a process known as synchronization. You can also change the model directly using the Properties view, the Java Beans view, or the visual canvas, and this change is then propagated in the source code. This two-way synchronization between the model and the source code is known as round-tripping and is one of the key feature of the Visual Editor.
Because the Visual Editor for Java works directly with the statements in the Java source code, you can modify them and see the changes reflected in the Visual Editor. The advantage of this is that you are not restricted to making changes with the Visual Editor -- you can edit the Java source file in another editor, re-open the Visual Editor, and see the effect of your modifications. The Visual Editor doesn't at any point execute Java beans that you are editing, so instead it must try to reverse engineer from the source code the Java beans that will be constructed at run time and the properties that will be set. If the source code doesn't follow the patterns recognized by the Visual Editor, then the Java beans shown on the visual canvas will be incomplete or different from those that actually appear at run time. This article describes in detail the source code patterns used by the Visual Editor, as well as problems that can occur when the source code is outside the list of recognized styles.
When the Java source is analyzed for patterns, the first step is to determine what Java beans are present. A Java bean must meet the following conditions:
- If the Java bean is to be rendered on the graphical canvas free-form, it must be declared as an instance field (unless it is added to a parent that is declared as an instance field).
- The field must start with
ivj, unless the class is a descendent ofjava.awt.Component. - A method must assign the field an instance using a constructor or a static method call.
Some examples will help explain these three conditions.
To be a Java bean included in the Visual Editor's model, a field
declaration must be present. In the class
MyClass the fields
ivjString, aString , and
aFrame are possible Java beans:
public class MyClass{
protected String ivjString;
public String aString;
private java.awt.Button button;
} |
Field name begins with ivj for non-visual Java bean
Some classes contain many fields that the user may not wish to see in the
Java beans model. This could include instances of URLs, FileDescriptors,
or Strings that are part of the working state of the class but should not
be included in the visual canvas. To restrict the number of unnecessary
Java beans on the visual canvas and in the Java beans view, fields must
start with ivj. An exception to this rule is
made for visual Java beans, which are displayed on the canvas with an
image of how they will appear at run time. (A visual Java bean is one
whose class extends java.awt.Component, either
directly or indirectly in its hierarchy.) The visibility of a field is not
used to determine whether it is a candidate Java bean.
String ivjString
|
This is a candidate Java bean because the field name starts
with |
String aString
|
The field name does not being with
|
java.awt.Button button
|
Even though the field name does not start with
|
Once a field has been determined as being a candidate Java bean that doesn't mean that it will appear in the Visual Editor's model. It must still satisfy the following rules to be included:
Method to instantiate the Java bean
For every Java bean that is included in the Visual Editor's model an object is created at design time. This object is used to determine the values shown by the Properties view for any unset properties, and if the Java bean is visual then a graphic of the live instance is shown on the canvas. After determining that a field is a candidate Java bean the Visual Editor code parser will look for a method that contains a statement responsible for setting the field to its initial value. A method is considered as being the one that sets the initial value if it has an assignment statement whose expression is a constructor or a static method call. The name or return type of the method, or its visibility, are not used in any way to determine whether it assigns the field or not. If there is more than one candidate method the first one that is defined is used. The following are examples of methods together with the reasons why every field is or isn't included in the model of Java beans.
private java.awt.Button button;
|
The button is recognized as a Java bean because the field is
assigned a value using the defaultConstructor of
java.awt.Button. This style of
method where the field is lazily instantiated in a get method
that returns it is the one used by the Visual Editor for new
Java beans that are added to the class being composed using
the palette. Lazy instantiation is a technique used where a
field is assigned a non-null value only if it is null, as
occurs with the assignment being done within the
if ( ivjButton == null ){..} block.
|
private java.awt.Button button;
|
Both button and ivjString are
included as Java beans in the Visual Editor model because the
method contains a statement that assigns the field using a
constructor. The method doesn't return either of the two Java
beans it instantiates, nor does it instantiate the fields
lazily, nor does it have a name that matches either of the
fields.
|
private java.awt.Button button;
|
ivjString is not included as a Java
bean because the assignment expression is to a literal
constant of "Frog". The expression assigning the field a value
must create the instance using either a constructor or a
static method call. The field button is included as a Java
bean because it is assigned a value by calling the static
method: MyButtonManager.getDefaultInstance();.
|
private java.awt.Button button;
|
button is not recognized as a Java
bean because the method that assigns it a value does so by
using a static field SINGLETON on
the class MyButtonlManager. Only
static method calls are recognized as Java beans assignment
expressions - not static field references.
|
private String button = new
|
button is not recognized as a Java
bean. Although it is assigned during its field declaration,
this is not sufficient because it must be assigned its initial
value within a method. The
createFields() method sets property
values on the button field, but because it doesn't actually
assign button with an instance, the
button field is rejected as a candidate Java bean.
|
Once a field has been recognized as containing a Java bean, it is then included in the model for the Visual Editor. All entries in the model are shown in the Java beans tree view and also on the visual canvas. An actual Java bean instance is constructed by the Visual Editor using the expression contained in the assignment expression. If the Java bean is visual, then an image of its graphic is used on the canvas. Otherwise it is shown with an icon and its name. The button instance created will be shown at its preferred size because it has no explicitly set size or bounds property.
When a Java bean is found in the source, the next step is to find its
initial property values. These are things such as a button's initial
label, a frame's size, or a panel's color. To determine the initial
property values, the method that was found to be the one assigning the
Java bean field with an instance, as described in the above sections, is
analyzed for its set methods that have the Java bean field as the
receiver. To be included as a candidate property value, the method name
must match that on the set method of the
java.beans.PropertyDescriptor. For the
majority of cases, this means that the method should be named with the
word set + property name and have a single
argument that has the same type as the property. For example, the method
public void setLabel(String aString) is the set
method for the label property of the class
java.awt.Button.
In the simplest case, a method is recognized as being the one that
initializes a Java bean because it assigns it a value, and the values of
set methods associated with PropertyDescriptors are applied to the live
instance. The method createFields() initializes
button, so it is recognized as being its
initializer method, and setLabel is the set
method for the label property.
private java.awt.Button button;
|
|
If there is more than one set method for the same property in the
initialize method, then the first one is used, as shown below where
setLabel is called twice with values of "Dog"
and "Frog".
private java.awt.Button button;
|
|
Try-catch blocks
Set methods within try blocks are recognized as being initial property values, while those in catch blocks are not. In the code below, the button is red but doesn't have the label "Dog", because catch blocks are not expected to be executed within normal program execution and therefore are not responsible for setting a Java bean's default state.
private java.awt.Button button;
|
|
Property values used in constructor arguments
The actual assignment expression is evaluated to construct the Java bean,
so in the example below, where button is
instantiated with the constructor
new java.awt.Button("Dog"), it will appear in
the visual canvas with the label "Dog". It also will appear with a red
background because of the
setBackground(java.awt.Color.red) method in the
initializer method for button.
private java.awt.Button button;
|
|
However, because there is no setLabel method
called for the button, although the label value is applied to the live
instance, the Java bean property is not recognized as being set in the
constructor and will not appear as a set value in the Properties view. Set
properties are shown with a > against
them in the Properties view, although unset properties are shown with the
value returned by the Java bean's get method.
Therefore, if the label property is set in the Properties view to another
value, such as "Cow", this will result in a new
setLabel method being generated. The
constructor argument will not be altered.
private java.awt.Button getButton() {
button = new java.awt.Button("Dog");
button.setLabel("Cow");
//...
} |
When a property value set method is found, the assignment expression is then evaluated to construct an instance of the object that is used as the argument to the set method that is invoked on an instance of the receiver. Not all expressions can be successfully evaluated, as described below in the section Expressions that can be evaluated.
When a set method is found whose receiver is a Java bean, it is only
evaluated by the Visual Editor if the set method is present on a property.
The list of properties of a Java bean is determined by introspecting the
class. Introspection is a process that tries to determine whether there is
an explicit BeanInfo class for the Java bean, and failing that, a default
one is created that matches up get and set method pairs by name. BeanInfo
classes are typically created to supply information that is used by a tool
such as the Visual Editor, such a property editor or customizer classes. A
common pitfall of the Visual Editor is that a property has not been
included in a BeanInfo class because the developer didn't want it to be
shown to the user in the Properties view; however they still want the
result of set methods in the code to be parsed and evaluated. In these
circumstances, the BeanInfo should be changed to return the
java.beans.PropertyDescriptor that defines the
set method. However hide it with
setHidden(false); so that it won't appear in
list of available properties in the Properties view. Another common error
is that BeanInfo classes do not return inherited properties, which
therefore prevents all of their set methods from being evaluated. To
correct this, the BeanInfo class should return the inherited properties in
its bean descriptor with the following code:
public BeanInfo[] getAdditionalBeanInfo(){
try {
return new BeanInfo[] {
Introspector.getBeanInfo(getBeanClass().getSuperclass())
};
} catch (IntrospectionException e) {
return new BeanInfo[0];
}
} |
Properties on the class being edited
In addition to being able to set properties on Java beans that are defined
in fields, the Visual Editor lets you set properties on the class you are
editing. The class being edited is treated differently by the Visual
Editor, because the receiver of the property sets methods is the
this instance. Whether the
this instance is included in the Visual
Editor's model of Java beans is determined by whether the class has any
properties. These properties would normally be shown in the Properties
view, so they should have get and set methods and are obtained by
performing introspection of the class. If the
this instance is included in the Java beans
model, it will appear in the Java beans tree view and visual canvas as for
any other Java bean, except that it cannot be deleted or renamed because
there is no field to remove or rename.
To determine the set methods that are responsible for creating the initial
state of the this instance, the Visual Editor
looks for a method called initialize(). If
this method doesn't exist, it is created the first time a property is set
on the this instance using the Visual Editor's
viewers. If a default constructor does not exist when the
initialize() method is created, then one will
be added to the class that with a method call to the
initialize() method. If the default constructor
does exist when the initialize() method is
created, it is only modified to call the
initialize() method if the constructor has no
other statements within it.
In the example code below, an instance for the class being edited is
created because MyPanel has settable properties
that it inherits from its superclasses. This instance is labelled
this in the Visual Editor. A default
constructor calls the initialize() method,
although for parsing, the Visual Editor needs the constructor or method
call to initialize() to be there. The
initialize() method calls
setSize(... and
setBackground(..., and both of these are
recognized as properties and applied to the
this Java bean instance. The receiver of the
methods can be explicit, such as
this.setSize(50,50), or implicit, such as
setBackground( java.awt.Color.cyan). Both are
equally valid.
public class MyPanel extends Panel {
|
|
The exception to the initialize() method being
used for property settings on the class being edited is if the class is an
applet. Applets extend either
java.applet.Applet or
javax.swing.JApplet and are designed to run
within a viewer launched by a Web browser. As part of their protocol,
applets have a method public void init() that
is called by the applet viewer to construct its initial state, and the
Visual Editor parses the init() method, rather
than initialize(), to look for initial
property settings. This is shown below with
MyApplet, with its size set to be 50,50 in the
init() method and its background to be cyan in the
initialize() method. The live Java bean,
however, is shown at 50,50 but without a cyan background, because the
initialize() method has no significance in
Applet subclasses. When properties are set through the Properties view,
the Visual Editor will detect whether the class being edited is an Applet
and generate the code in the correct method.
public class MyApplet extends Applet {
|
|
Relationships between Java beans
The above examples show set methods whose argument expression fully
describes how to construct the object that will be used for the set
method. For example, the argument of the method
setBackground is the statement
java.awt.Color.red. In addition to the
statement for creating the argument object being fully described between
the parenthesis of the set method, the argument object can be a reference
to another Java bean -- a reference to the field name that describes the
Java bean, or to the method that instantiates the Java bean if the method
returns the Java bean. If the argument expression does reference a field,
then this field must have followed the rules to be recognized as a Java
bean by the visual editor -- namely it must have a method that
instantiates it and it must begin with ivj
(unless it is a visual Java bean).
Java beans defined as instance variables
In the example below, the field ivjColor is
recognized as a Java bean because it begins with
ivj (java.awt.Color
does not descend from java.awt.Component and is
not a visual Java bean, otherwise any field name could be used). The
getButton() method contains an assignment
expression that sets ivjColor using a
constructor, so ivjColor is included as a Java
bean in the Visual Editor model. The argument to
setColor(ivjColor) is a reference to the field
itself, so the Visual Editor will use the actual Java bean instance it
creates for ivjColor as the argument object
when it invokes the method.
private java.awt.Button button;
|
|
Java beans defined as method variables
In the code below, even though the field
ivjColor is scoped within the method that uses
it and is not an instance field, it is still recognized as being a Java
bean by the Visual Editor:
private java.awt.Button button;
|
|
Java bean instances assigned values from static fields
Java bean instances must be assigned with either a constructor or a static
method call. Because ivjColor is assigned a
value using the public method call
java.awt.Color.red, it is not recognized as
being a Java bean by the Visual Editor. The warning sign shown on the
visual graphic for the button indicates an error applying a
property-to-button instance. This is described more in the section
Expressions that can be evaluated below. This is
different from property values where static fields can be used (for
example,
button.setBackground(java.awt.Color.red) is
valid), and the rule applies only to initialization of a field
representing a Java bean.
private java.awt.Button button;
|
|
Non-visual Java bean fields must start with ivj
Field names for non-visual Java bean instances must begin with
ivj. In the code below, because the
java.awt.Color instance field name is color
with no ivj prefix, it is not recognized as a
Java bean. The Visual Editor VM recognizes this and puts a yellow warning
sign over the graphic for the Java bean to indicate that some of its
properties were not applied correctly.
private java.awt.Button button;
|
|
Property values assigned as the result of method calls
If a property value's set method argument is not directly to the field
ivjColor but is instead to a method call such
as getColor(), then the Visual Editor can
process it as long it recognizes that
getColor() is an initializer method for a Java
bean. In the code below, the Visual Editor has recognized that
ivjColor is a Java bean and that the
getColor() method returns the field
ivjColor. It therefore sets the button's
background color to the value of the field
ivjColor, which is assigned a value with the
constructor new java.awt.Color(255,0,0).
private java.awt.Button button;
|
|
The relationships shown up till now have been for property values, where a
set method that is part of a property is used to establish the link
between the two Java beans. In addition to set methods described in
properties, other methods can establish relationships for different types
of Java bean classes. An example of this is the relationship between a
java.awt.Container, the root superclass of the
visual classes such as java.awt.Frame and
javax.swing.JPanel, and its child components.
No single argument set method describes this property, so the Visual
Editor looks for specific add(Component...)
methods to determine whether a Java bean component is a child of the
container or not.
In the code below, the method
panel.add(getButton(),null) creates the
relationship between the panel Java bean and the button, adding the button
as a child component to the panel.
private java.awt.Panel panel;
|
|
In addition to
public void add(java.awt.Component child, Object constraint)
the following methods on container will be recognized by the Visual Editor
as creating a parent-child relationship between a container and a
component.
public void add(java.awt.Component child); public void add(String name, java.awt.Component child); public void add(java.awt.Component child, Object constraint, int index); |
Although all of the above methods are recognized as being a component
added as child of a container, for the live Java beans instances, the
indexed add method is always used by the Visual
Editor's JVM (the last in the above list). All three of the methods,
however, use the java.awt.Container method
protected void addImp(Component aComponent, Object aConstraint, int anIndex),
so if you have any specialized subclass behavior that you want to be
used by the Visual Editor JVM, then you should specialize the protected
method to ensure that your code will be executed. In addition to
java.awt.Container and the relationship to its
child component Java bean, there are other classes that have relationships
that are recognized by the Visual Editor.
The relationship between a javax.swing.JTable
and its child columns is recognized by the method
public void addColumn(TableColumn). To help
you see the columns, preview data with five rows is created on the visual
canvas. A JTable can either show its explicit child columns, or else
determine the number of columns from its model by calling the method
public int getColumnCount(). Which of these
two techniques is used by the JTable, both at run time and design time by
the Visual Editor, is determined by the value of the boolean property
autoCreateColumnsFromModel:
import javax.swing.JTable;
|
|
A JTabbedPane has its children defined by the
method
public void addTab(String title, Icon icon, Component
component, String tip). The component argument is the child tab component, although the other
arguments are used to evaluate all of the parameters passed to the actual
method called on the Visual Editor's Java bean. In addition to the four
argument methods, the Visual Editor will parse and recognize the shorter
methods
public void addTab(String title Component component)
and
public void addTab(String title, Icon icon, Component component).
import javax.swing.*;
|
|
Expressions that can be evaluated
After parsing the source and creating a model of the Java beans and their
initial property values and relationships, the Visual Editor for Java then
creates actual prototype instances. It does this on a separate target VM
from the one in which Application Developer is running. The prototype
instances are used by the Properties view to show the value of unset
properties, and if the Java bean is descended
from java.awt.Component, then its graphic is
shown on the visual canvas.
To create the prototype instances, at no point is the class that is being
edited actually instantiated. Instead, each expression that instantiates a
Java bean is evaluated and methods are executed on the target VM. Because
there is no way to evaluate Java statements in a JRE without compiling
them into bytecodes, the Visual Editor parses each expression to create a
set of find-grained statements that are then evaluated on the target VM
using the Java reflection API. For example, in the statement
button.setBackground(java.awt.Color.red); the
argument value java.awt.Color.red is parsed and
determined to be a reference to the static field
red on the class
java.awt.Color. In the target VM, the class
java.awt.Color is looked up and the field value
retrieved using
Class.forName("java.awt.Color").getField("red").get(Class forName("java.awt.Color");.
The resulting color is then used as the argument to the set method. For
example:
button.getClass().getMethod("setBackground", new
Class[] { java.awt.Color.class }).invoke(button,color); |
Property value set method throws an exception
If a property set method throws an exception on the target VM, the Visual Editor will re-create the Java bean that is the receiver of the method, but will flag the errant property as being in error. The property that caused the exception will then not be applied to the prototype instance. Thus the live Java bean remains a working instance for longer so that the result of the remaining properties can be seen. To indicate that an error occurred when a set method was applied, a warning sign is shown on the visual canvas and in the Java beans view. If you select a Java bean with an error, the exception message, together with the name of the errant property, is displayed in the workbench status bar.
For example, the orientation property of
javax.swint.JScrollBar can only be 0 (vertical)
or 1 (horizontal). In the code below, when the value 9 is sent to the
target VM, the prototype instance for
JScrollBar throws an illegal argument
exception. The Java bean is then re-created without the bad orientation
property applied, although its other properties such as size are still
set. A yellow warning triangle indicates that the Java bean encountered an
error, so there is a mismatch between the data shown on the visual canvas
and the data that would be shown at run time.
private javax.swing.JScrollBar jScrollBar;
|
|
A warning sign is also shown in the Java Beans viewer, and when this is selected, the name of the errant property and the exception error message is shown in the workbench status bar.
Expression too complex to be evaluated
In addition to errors that occur on the target VM because of exceptions thrown by property set methods, some expressions are too complex for the Visual Editor to evaluate through reflection. Examples include methods that reference any program state other than a Java bean field directly. Expressions that reference non-static inner classes also can't be evaluated because they are too complex to be constructed through reflection, since non-static inner classes must be created only from within the outer class, which is the class being edited.
In the code, below the argument to the
setModel(... method is an anonymous inner
class. This cannot be instantiated by the target VM because it requires
the creation of the outer class, which the one being edited may have not
even compiled yet. Because the model cannot be applied, the preview data
used by the Visual Editor of a 5x5 row column grid is shown, together with
a yellow warning sign. The status bar shows that the expression is too
complex for the Visual Editor to evaluate.
private javax.swing.JTable jTable = null;
|
|
The error message shown in the status bar of the workbench indicates that the warning error is because the model property's set method argument is too complicated to be evaluated. The error symbol is shown against the JTable because the Visual Editor preview may look different at design time than at run time (when the set method will be applied, as the class has been compiled).
In addition to inner classes, some types of expressions are outside the
scope that the Visual Editor can parse and evaluate correctly. In the code
below, the initialization expression
button.setLabel(x); cannot be evaluated for two
reasons. First, it references a field x that is
a program state that cannot be evaluated by the target VM. If the field x
were renamed to ivjX, it would be recognized
as a non-visual Java bean, but in this case it is still too complex to
evaluate because arithmetic expressions that are not actual method calls
but are instead optimized by the Java compiler (such as +, -, /, or *)
cannot be expressed using the Java reflection API.
private java.awt.Button button;
|
|
Selecting the button will show the reason for the error in the status bar message:
Use of non-null constructors to instantiate a Java bean
In the code below, because the constructor for
MyJavaBean references
this as its argument,
this cannot be evaluated by the target VM using
reflection. The only exceptions to this rule are
java.awt.Dialog,
java.awt.Window, and any subclasses of either
of these when they are used within a Frame, and the prototype instance
will be instantiated correctly.
private MyJavaBean ivjMyJavaBean;
|
|
Even if the Java bean is visual, no graphic for it is shown in the design
view because it cannot created, and a red X
symbol is shown instead. This also applies to all Java beans that throw
exceptions during the construction, and selecting the Java bean in the
Java beans viewer or on the design canvas will show the reason for the
exception in the status bar.
Strings from resource bundle files
In the code below, the initialization string
resbundle.getString("OK_label") references the
static field resbundle, so it cannot be
evaluated. Rather than flagging this as an error however, the Visual
Editor recognizes that this is the syntax for retrieving a string value
from a .properties file, and it calls the
property set method with a String value of the bundle key with curly
braces around it.
private static java.util.ResourceBundle resbundle
|
|
This section illustrates a number of common issues related to code-parsing patterns. They are based on code samples created either by another builder or included in Swing documentation that requires modification before it can be used in the Visual Editor.
In the first scenario, the JPanel is defined as an instance field, but the
jButton isn't. The JButton is defined locally in the method that
instantiates the JPanel and added directly to it. The Visual Editor
includes the JPanel because it is a field (see
Recognizing a Java Bean), and it includes the button
on the panel because it is an argument to the
add(Component,Object) method even though it is
a local method field and not a class field.
private javax.swing.JPanel getJPanel(){
|
|
In the next scenario, the field that adds the button to the jpanel is commented out. The panel remains on the graphical canvas, but the button does not. It is no longer a child of the jpanel, so it is not shown in the Swing JPanel instance, and because it is not defined as an instance field, it is not rendered as a top-level Java bean.
private javax.swing.JPanel getJPanel(){
|
|
In the last scenario, the declaration of the button field is moved from
the method getJPanel() to be an instance field
in its own right. Even though the button is still no longer a child of the
jpanel because it satisfies the rules to be rendered on the graphical
canvas (it is declared as an instance field and assigned a value in a
method) it appears on the Visual Editor alongside the jpanel.
private JButton jButton = null;
|
|
This sample begins with the assumption that the code you wish to parse
with the Visual Editor should appear as shown below: a JPanel with a
JTextArea and a JButton using
GridBagLayout.
The code that is originally written to create this is as follows:
| Before |
import javax.swing.*;
|
The Visual Editor will not parse this code pattern to show the desired JPanel with the JTextArea and JButton because of the following differences between the source and the recognized code patterns.
The method that initializes the properties and relationships for the class
being edited (the MyPanel class) is named
jbInit(). For the Visual Editor it is
named initialize() to be parsed correctly.
| Before | After |
private void jbInit()
|
private void initialize()
|
The fields jButton1, jTextArea1 and
gridBagLayout1 do not have a method that
instantiates them, as they are constructed as part of the their field
declarations. The instantiation code should be moved from the field
declarations to the initialize() method.
gridBagLayout1 is not a descendent of
java.awt.Component, which usually requires its
field to be prefixed with ivj. This is a
Visual Editor parsing rule where fields that are typed to classes that
implement java.awt.LayoutManager can have any
name.
| Before | After |
public class MyPanel extends JPanel{
|
public class MyPanel extends JPanel{
|
The GridBagConstraints instance cannot be
created during the argument to the method
this.add(Component child,Object constraint);
For the Visual Editor to parse the code correctly, a local method field
should be used with the same initialization string that is passed to the
method argument. Also, for GridBagConstraints,
although the layout manager allows the same constraint instance to be
shared across components, the Visual Editor expects a unique
GridBagConstraints object to be created each
time. In the following example, two new constraints are created,
consB1 and consT1:
| Before | After |
private void initialize()
|
private void initialize()
|
After the following changes are made, the Visual Editor for Java can be used successfully with the MyPanel classes:
- Rename the
jbInit()method toinitialize(). - Move the instance field initialization to assignment expressions
within the
initialize()method. - Declare the
GridBagConstraintarguments toadd(Component,Object)to new unique method fields.
The following example shows a sample class
HelloWorldSwing that creates a JFrame and adds
a JLabel within the
static void main(String[] args) method.
import javax.swing.*;
|
|
The static main(String[] args) method is used
by classes that are launched by the visual machine by being arguments to
the java command. The Visual Editor does not
use any special rules to parse the
main(String[]) method. To be parsed,
ivjFrame should be made an instance field:
| Before | After |
import javax.swing.*;
|
import javax.swing.*;
|
The contentPane of the JFrame is retrieved using
getContentPane() and the JLabel is then added
to it. However, the Visual Editor for Java does not support this implicit
use of Java beans, and the contentPane must be
declared as a field and assigned using a constructor. This means that any
code that occurred in the JFrame during the creation of its contentPane
will not occur, so if you have subclassed JFrame and put custom
initialization logic for its contentPane, this
should be moved out into a separate JPanel subclass that should be
explicitly created and used as the contentPane.
| Before | After |
public static void main(String[] args){
|
public static void main(String[] args){
|
This article has shown the rules by which the Visual Editor for Java interacts with Java source code. By understanding these rules and programming with them, you can make the Visual Editor recognize a wide number of source styles and convert code from other builders.
Question:
The article is very informative and exhaustive. I have one query
which I would be grateful if you could solve. I have a Java bean with a
property that I have declared as type Object. Actually I am trying to put
in an array of String objects in it. In the initialize() method of a Java
bean, if I try write textfield.setValue(new String[] {"ABC","XYZ"}) it
gives the following error: java.lang.InitializationException. The
expression is too complicated to be evaluated. In fact it gives this
exception whenever I use any array in the setValue. Please advise. Thanks
and regards, Paramjit Singh
Response from author:
Thanks for the feedback on the article. The Visual Editor for Java
works by parsing the source and looking for recognized patterns that it
can use to determine what the Java beans are, as well as their
interrelationships and properties. For properties, the set method argument
is analyzed and executed, so in your code the Visual Editor is detecting
that the value property is the expression 'new String[] {"ABC","XYZ"}'.
Because Java itself doesn't have an expression evaluator that we can use,
the Visual Editor has to manually tokenize the expression to work out how
to create the required object, in this case a String[] with two initial
items. In some of our early releases we were unable to evaluate array
expressions, but this was fixed before the V5.0 GA. Is it possible that
you are running an early availability (EA) version?
If the problem
persists, please forward some sample source code together with screen
shots.
Joe Winchester is a member of the WebSphere Tools Development team working on the Visual Editor for Java for the Software Solutions group in Hursley, United Kingdom. You can reach Joe at winchest@uk.ibm.com).
Rich Kulp is an Advisory Software Engineer at IBM Raleigh Lab, North Carolina. He works on WebSphere development tools and is a member of the team working on the Visual Editor for Java. You can reach Rich at richkulp@us.ibm.com.
Dr. Gili Mendel is a Senior Advisory Software Engineer at IBM Raleigh Lab, North Carolina. He works on WebSphere development tools and is a member of the team working on the Visual Editor for Java. You can reach Gili at gmendel@us.ibm.com.
Peter Walker is an Advisory Software Engineer at IBM Raleigh Lab, North Carolina. He works on WebSphere development tools and is a member of the team working on the Visual Editor for Java. You can reach Peter at walkerp@us.ibm.com.
Srimanth Gunturi is a Staff Software Engineer at IBM Raleigh Lab, North Carolina. He works on WebSphere development tools and is a member of the team working on the Visual Editor for Java. You can reach Sri at sgunturi@us.ibm.com.
Jeffrey Myers is a member of the WebSphere Tools Development team working on the Visual Editor for Java for the Software Solutions group in Raleigh, North Carolina. Jeff can be reached at myersdj@us.ibm.com.



