Comments
Richard Davies wrote: The UK has a good crop of technology pioneers in cloud computing - for example ElasticHosts, FlexiScale, Flexiant, OnApp - and also some strong government initiatives such as G-Cloud. We will have to see whether this kind of technical leadership converts into swift mass-market adoption or not.
Cloud Expo on Google News

SYS-CON.TV
Cloud Expo & Virtualization 2009 East
PLATINUM SPONSORS:
IBM
Smarter Business Solutions Through Dynamic Infrastructure
IBM
Smarter Insights: How the CIO Becomes a Hero Again
Microsoft
Windows Azure
GOLD SPONSORS:
Appsense
Why VDI?
CA
Maximizing the Business Value of Virtualization in Enterprise and Cloud Computing Environments
ExactTarget
Messaging in the Cloud - Email, SMS and Voice
Freedom OSS
Stairway to the Cloud
Sun
Sun's Incubation Platform: Helping Startups Serve the Enterprise
POWER PANELS:
Cloud Computing & Enterprise IT: Cost & Operational Benefits
How and Why is a Flexible IT Infrastructure the Key To the Future?
Click For 2008 West
Event Webcasts
On JavaBeans Customization
On JavaBeans Customization

JavaBeans, now in its third year, is proving to be a powerful component model. Whether it's the Java e-commerce framework or the Java platform for the enterprise, JavaBeans is at the heart of many new and exciting technologies. The JavaBeans model provides a framework to build, customize, run and deploy Java software components. While there are numerous books and articles on JavaBeans, not many of them deal with the customization aspect of JavaBeans.

An object that conforms to the JavaBeans specs is called a JavaBean or, more generally, a bean, which at runtime is like any other object. What distinguishes it from other Java objects is that it can be manipulated with visual builder tools. This process includes customization and connection, which means that you can visually customize beans and connect them to assemble an application.

Let's discuss customization using the Pie Chart bean (part of the visualization bean suite developed for my book, The Awesome Power of JavaBeans) shown in Figure 1. If you want to use this bean, you'll probably customize it to suit your application, which may include changing the size and position of the pie as well as the location of the legends. You can customize the bean visually by using a bean builder tool. Once you customize it, you may want to save the configuration for future use by using the Java serialization feature. Sun's BeanBox, which comes with the BDK, is an example of a visual builder tool that allows you to customize, serialize and connect beans. Most of the Java IDEs provide similar tools.

Property Sheets
To customize a bean visually, you need a tool to view and edit its properties -Êbuilder tools typically provide property sheets for this purpose. Figure 2 shows the property sheet generated by the BeanBox for the Pie Chart bean. Every time you insert a bean or click on the existing bean in the BeanBox frame, the BeanBox generates a new property sheet. To generate a property sheet, the builder tool obtains the property names and their valuesfrom the bean using a mechanism called introspection.

Introspection
According to the JavaBean specs, three basic features describe a bean: properties, methods and events. The introspection mechanism analyzes the bean classes to obtain these features. A bean author can help the introspection process by providing a design-time class, BeanInfo, that is specific to a runtime bean class. For example, PieChartBeanInfo is the BeanInfo class for PieChart. Bean authors can provide descriptions of bean features in the BeanInfo class. In the case of a property, its description may include display name, access methods and short text.

How does introspection work? The process first checks the BeanInfo class to obtain a bean's feature (property, method and event) descriptions. If the bean author doesn't provide any information about properties (or other features) in the BeanInfo class, the introspection process uses the low-level reflection API (java.lang.reflect and java.lang.Class) to obtain it. Using these APIs, it probes the bean class to obtain its fields and methods, then deduces a bean's feature descriptions by matching the method signatures with the naming conventions defined by the JavaBeans specs.

The naming conventions for properties define the signatures for setter and getter methods. The former sets the property and the latter reads it. Here is a naming convention defined for a simple property:

  • The setter method:
    public void set(PropertyType t)

  • The getter method:
    public <Property Type> get<PropertyName) {}

    The following example shows the setter and getter methods for the Graph Color property:

    public void setGraphColor(Color color){//code } public Color getGraphColor(){// code}

    The other types of properties, which include indexed and boolean, have similar naming conventions.

    Editing Properties
    Once the builder tool obtains the exposable properties, it creates a suitable edit field for each one. For example, the edit field for the plotTitle property in the Pie Chart bean is a text field (TextField or JTextField). Text fields are adequate as long as a property is simple, that is, of Java primitive type (short, int, byte, char, etc.). When a property is of enumerated type, the property sheets typically provide combo boxes (Choice in AWT; JComboBox in JFC).

    To edit a property, each property type needs to be associated with a property editor. For simple properties, a property value can be expressed as a text string. The property editor converts the property value obtained from the bean to a text string so as to display it in the text field. When the user inputs a value in the text field, it converts the inputted text string to the corresponding primitive type.

    When you start writing real-world beans, you'll realize that Java primitive types aren't always adequate to represent different types of bean attributes. Take the background and foreground colors in the Pie Chart bean, for example. In this case the property type is Color, which is a class in the AWT. You can't enter a color name in the edit field because the text type property editor can't convert a color name to a Color object. What you need is a special property editor that does this conversion. Builder tools often provide custom-written property editors for commonly used properties such as Font and Color. If the property type is a class defined by the bean author, then she/he needs to write a property editor for that class.

    Property Sheet Limitations
    While the property sheet concept is a vast improvement over manual customization (through programming), it's inadequate to customize complex beans. Here are some limitations:

  • Bean authors can't choose the GUI components they like for editing properties. Consider the Pie Chart bean example again. Let's say you want to move the pie to the right. You can do so by entering a value in the Pie Center X Increment field. It's hard to guess the right increment the first time. Before you get the pie position right, you typically enter the increment values a few times. For this kind of operation you'd probably prefer a different component to move the pie.
  • Property sheets are static. Edit fields for properties can't be added to or removed from the sheet depending on the value entered in another edit field.
  • Notice that the property sheet for the Pie Chart bean displays its properties in a random order. Before you start editing the properties, you may have to mentally group the properties along the functional lines. This problem gets worse when there are a large number of properties. Imagine a bean that has more than a hundred properties - not uncommon in complex beans. You'd have to scroll the property sheet many times to get an overall picture. Even with the Pie Chart bean, which has fewer properties, customizing is easier when properties are grouped together.
  • It's not always easy to capture the semantics of the customization process just by looking at the property sheet. Sometimes the process may require properties to be entered in a certain order.
  • You often have to configure a bean at runtime. But property sheets are available at design time only because a builder tool is needed to construct the sheet.

    Customizers
    The JavaBeans model provides an alternative to property sheets. It specifies an interface called Customizer to enable bean authors to implement a bean-specific customizer. Such a customizer can be a simple panel with related properties grouped together or a sophisticated wizard that allows the user to navigate through a hierarchy of screens. Since builder tools recognize any customizer that implements the Customizer interface, it can be launched from any builder tool that has the bean installed.

    Customizer Interface
    The Customizer interface is simple and has only three methods:

    1. setObject(Object bean): The builder tool calls this method to pass the target bean instance to the customizer. It is called only once, which is before the builder tool launches the customizer.
    2. addPropertyChangeListener(PropertyChangeListener listener): This method adds a propertyChange event listener. By registering as a listener, the target object(s) (typically the builder tool and property sheet at design time or bean or bean context at runtime) can receive notification and the modified value of the property. When the target object receives a propertyChange event, it retrieves the setter Method object and the property value from the PropertyChangeEvent object. Using this Method object and the property value, the target object then invokes the setter method in the bean to modify the property.
    3. removePropertyChangeListener (PropertyChangeListener listener): This removes a property change event listener.

    Builder Tool Interaction
    To run the customizer at design time, the builder tool first fetches the customizer class from the BeanInfo class associated with a bean. Using the customizer class, it creates an instance of the customizer object by calling the newInstance() method. The builder tool then embeds the customizer object in a dialog box and launches it.

    Before the builder tool launches a customizer, it calls the setObject(Object bean) method in the customizer object and passes the bean instance as the parameter. It also registers for the propertyChange events. The customizer has to fire these events whenever a property is modified. When the customizer fires the event, it sends the new property value encapsulated in the PropertyChangeEvent object.

    Designing Customizers
    Choosing the right graphical user interface for presenting and editing properties is an important part of the design. Besides being user-friendly and interactive, the GUI should capture the semantics of customization. In other words, it should be intuitive for a user to start using it just by looking at the GUI.

    If you intend to provide a customizer for your bean, start the customizer design while you're designing the bean itself. Design your bean's properties to be compatible with the customizer GUI you have in mind. For example, I wanted to have "+" and "-" buttons to increment and decrement the pie size in the Pie Chart bean (see Figure 3). I originally intended to have just one property, Pie Diameter, to represent the pie size. In order to develop a more interactive customizer GUI, I created one more property, Pie Diameter Increment, to represent the increments or decrements relative to Pie Diameter. Thus, when you click the "+" button, the pie diameter is incremented by a certain amount. Likewise, when you click the "-" button, it is decremented by the same amount. With the Pie Position property, I added two more properties: Pie Position X Increment and Pie Position Y Increment to represent the increments (decrements) to the pie position in X direction and Y direction, respectively.Figure 3 shows the Pie Chart bean customizer, which provides a better graphical interface compared to its property sheet. You can adjust the size and position of the pie smoothly by clicking the "+" and "-" buttons. Similarly, you can adjust the position of the legend by clicking the appropriate "+" and "-" buttons.

    Implementing a Customizer
    Once you design the customizer GUI, implementing the customizer class is just a matter of writing the code for the user interface and reading/writing properties. Building a sophisticated customizer may require a lot of programming, but you can develop it in such a way that most of the code can be reused.

    A customizer class has to meet the following requirements to enable builder tools to launch it:

    1. It must implement the Customizer interface. This is to enable the builder tool to recognize the customizer and to obtain the bean instance, which can be passed on to the customizer. Using this bean instance, the customizer can fetch and modify a bean's properties.
    2. It has to be a subclass (direct or derived) of the java.awt.Component class. This is to enable builder tools to embed the customizer in a dialog box.
    3. It must have a constructor with no arguments. This is to enable the builder tool to launch it. If constructors with arguments are allowed, builder tools wouldn't know which constructor to call (in case there are many) or what values to pass as parameters.

    The customizer UI will have different types of GUI components depending on your design. The event-handling code for these components should fetch and set property values. Since the customizer object gets the bean instance, it can directly call any public methods in the bean. This means that the customizer can directly invoke the getter and setter method to get and set a property in the bean. While you can build a customizer easily this way, it's not a good solution for the following reasons:

  • Property changes in the customizer aren't reflected in the property sheet. In the majority of bean builder tools, when the customizer is launched, the property sheet doesn't go away. Changes made to the property in the customizer have to be reflected in the property sheet as well because the customizer can't access the property sheet directly.
  • Code isn't reusable because getter and setter methods are used explicitly.
  • Code may require maintenance as you may need to change it in a number of places if a property name or type changes.

    An appropriate solution would be to use the reflection API to obtain the getter and setter methods of a property and fire the propertyChange events to set its value. The Pie Chart bean customizer uses this approach.

    Pie Chart Customizer
    The Pie Chart bean is part of a plotter bean suite. The other beans in this suite include XY Plot, Histogram, Line Chart and Bar Chart beans. The plotter bean customizers have many similarities. To capture the behavior common to all the chart bean customizers, I developed two common classes: CustomizerImpl and CustomizerUtil. The former implements the Customizer interface and the latter has a number of factory methods that create edit fields for different types of properties. The Pie Chart bean customizer class extends the CustomizerImpl class and uses the methods in CustomizerUtil class. The same is true for other plotter beans.

    CustomizerImpl Class
    As mentioned before, the customizer component is expected to be contained in a dialog box, so a customizer class can't be a subclass of Frame (JFrame) or Dialog (JDialog). Furthermore, the customizer class should be a container because it needs to house a number of components for editing. The logical choice would be to subclass Panel (JPanel). The CustomizerImpl class shown in Listing 1 does just that. It extends JPanel and implements the Customizer interface.

    As the listing shows, the CustomizerImpl class has three instance variables:
    1. bean: Holds the target bean instance. Since the setObject() method is called only once, this variable saves the bean instance.
    2. pcs: Holds the PropertyChangeSupport instance. The propertyChange event registration methods call the corresponding methods in pcs.
    3. title: Holds the customizer title. The addNotify() method, which is called only when the component receives a parent, sets the customizer title in the parent.

    The instance variables, bean and pcs, are set in the setObject() method. The createGUI() method creates the GUI components and is called only after the target bean instance is received. It is an abstract method, which means that subclasses of CustomizerImpl provide the actual code.

    CustomizerUtil Class
    The CustomizerUtil class has a number of utility methods that help to create edit field components, which include JTextField and JComboBox. This class uses the reflection API to get and set a property value.

    As an example, see Listing 2, which shows the createJTextField() method. This method first constructs a JTextField component. It then obtains the actual property value from the bean by calling the getProperty() method (see Listing 3). Using the property name string, getProperty() method first constructs the Method object for the property's getter method. The Method object executes invoke() to invoke the getter method.

    The createJTextField() method also has the code to set the property. When the user types a value and hits Enter, the JTextField fires an action event. To handle this event, createJTextField() registers with the JTextField to receive action events. The event-handling code for the action event is in an anonymous class in which the actionPerformed() method first fetches the text entered by the user from the JTextField and converts the value to an appropriate object. It then calls the firePropertyChangeEvent() method in pcs.

    Listing 4 shows the code to create "+" and "-" buttons for incrementing and decrementing a property. This method uses a highly reusable class, IncrButtonAdapter, which is an adapter class for the action event (see Listing 5). An IncrButtonAdapter instance is constructed for each button. The property name and increment intervals are passed as arguments to this constructor. The actionPerformed() method, which is called whenever the increment button is clicked, first fetches the property value from the bean, then adds the increment to this value and calls the firePropertyChangeEvent() in pcs. The IncrButtonAdapter class is used by pie and legend properties in the Pie Chart bean customizer.

    PieChartCustomizer Class
    Listing 6 shows part of the PieChartCustomizer class, which extends the CustomizerImpl class. It overrides the createGUI() method, which calls createLabelsPanel() and createColorPanel() methods to create labels and color panels. It also calls the createIncrPanel() method to create increment panels for pies and legends. As you can see from the listing, these methods call static methods in the CustomizerUtil class to create components for editing.

    Registering the Customizer
    The customizer has to be registered for the builder tool to launch it. The BeanDescriptor class is the only class that holds the customizer class. You can set the customizer class by using one of its constructors. The BeanDescriptor class has two constructors:

  • BeanDescriptor(Class beanClass)
  • BeanDescriptor(Class beanClass, Class customizerClass)

    The second constructor is used to register the customizer. If you use the first constructor, the builder tool assumes that the bean has no customizer. The code to register the customizer goes in the BeanInfo class. The example below shows how the Pie Chart bean customizer is registered. This code is taken from the PieChartBeanInfo class.

    public BeanDescriptor getBeanDescriptor(){ BeanDescriptor bd = new BeanDescriptor(PieChart.class, PieChartCustomizer.class); // Other stuff return bd; }

    A bean's own BeanInfo class is the only place where you can register a customizer. This means that building a BeanInfo class for that bean class is a must. This is because builder tools won't recognize the customizer even if the customizer is registered in a bean's superclass BeanInfo.

    Customizer at Runtime
    Although the availability of customizers at runtime is often desirable, the JavaBeans specification makes no mention of runtime customizers. You can provide this facility, however, by adding a few more methods to your bean. The program that launches the customizer can reside in the bean itself or in the bean context (container).

    To launch the customizer, you can use the button, pop-up menu or any suitable component depending on your bean and the application. The Graphics Viewport bean shown in Figure 4 provides a pop-up menu that can be triggered by right-clicking. (You can download this bean from my Web site at www.execpc.com/~larryhr/gvbean.html and use it to draw a variety of shapes and text.) This menu contains the items customize and serialize.

    The customizer class itself is a property in the Graphics Viewport bean. This means that the class can be set by the setter method and fetched by the getter method. The bean context or application that uses the Graphics Viewport bean can call these methods to register and launch the customizer.

    Listing 7 shows the event-handling code (which is in the Graphics Viewport bean itself) for the Customize menu item. As you can see, the actionPerformed() method first fetches the customizer class and passes it as a parameter to launchCustomizer() to launch the customizer.

    Launching the Customizer
    Listing 8 shows the launchCustomizer() method, which:
    1. Creates an instance of the customizer object
    2. Calls setObject() method to pass the bean instance to the customizer
    3. Registers for the propertyChange event

    In the event-handling method it retrieves the property values from the PropertyChangeEvent object and calls the setProperty() method (see Listing 9). This method uses the Method class to invoke the setter method.

    Bean as a Standalone Application
    Figure 5 shows the customizer for the Graphics Viewport bean. This customizer is much more comprehensive than the Pie Chart customizer. With it you can set the drawing parameters and also draw shapes and text. Since this customizer can be launched at runtime, you can use the Graphics Viewport bean as a standalone application.

    To make a bean run as a standalone application, you need to add the main() method. Starting with Java 2, a jar file can be made executable. This means that you can run a bean that has the main() method by executing its JAR file. For example, to run the Graphics Viewport bean, just type java -jar grbean.jar.

    To make a JAR executable, you need to include an attribute called Main-Class in the JAR manifest file. Following is the example from the grbean.jar manifest file.

    Main-Class: com.vistech.viewport.GraphicsViewport

    Name: com/vistech/viewport/GraphicsViewport.class Java-Bean: True

    This brings up another issue: Should the runtime and design-time customizers be the same? There is nothing to prevent you from having two customizers - one for design time and one for runtime. You can use the same Customizer interface to implement these customizers.

    Conclusion
    Property sheets are simple and don't require a lot of programming effort. They're inadequate, however, when beans are complex and have a large number of properties. We can overcome most of the limitations of the property sheet by building a special-purpose customizer. The Customizer interface is a simple but powerful API that can be used to develop user-friendly customizers to configure complicated beans. However, writing a good customizer requires a lot of programming effort. Unlike property editors, which are property specific, a customizer is specific to a bean. So if you make changes to the target bean, you may have to modify the customizer as well.

    References
    1. Rodrigues, L. (1998). The Awesome Power of JavaBeans. Manning Publications.
    2. Sun Microsystems, JavaBeans API Specification Version 1.01, July 1997.
    3. Rodrigues, L. (1997). "Java, The Next Generation: JavaBeans." Java Developer's Journal, Vol. 2, Issue 1, January.

    About Lawrence Rodrigues
    Lawrence Rodrigues is a senior consultant with Compuware Corp., Milwaukee. He has been developing Java applets and applications, is a contributor to the book "Professional Java: Fundamentals," by Wrox Press, and is also a judge at JARS. Besides Java, his current interests include Image Visualization and Analysis, Computational Geometry and Image Data Compression.

  • In order to post a comment you need to be registered and logged in.

    Register | Sign-in

    Reader Feedback: Page 1 of 1

    Latest Cloud Developer Stories
    Swisscom, the Swiss telecom, is going into the cloud business. Its subsidiary Swisscom IT Services AG has signed up with Red Hat as a Certified Cloud Provider and launched a public cloud Infrastructure-as-a-Service (IaaS) cloud targeting enterprise-class customers primarily in ...
    Apache Deltacloud, the Red Hat-contributed ReSTful API that abstracts differences between clouds so services on any cloud can be managed – provided of course there’s a driver – has graduated from the Apache Foundation’s incubator and is now a full-fledged Top-Level Project (TLP)....
    In a surprise move on Tuesday, January 10, Oracle wheeled out its Big Data Appliance. That’s the one it said in October would be ready sometime in the first half. Only nobody believed it meant early in the first half. Heck, it’s not even clear anybody thought Oracle could make ...
    Rackspace Hosting, the service leader in cloud computing, on Thursday announced its acquisition of SharePoint911, an industry leader in SharePoint consulting, training, and "JumpStart" services within SharePoint. The unification of both companies provides capabilities to deliver ...
    CloudLinux, Inc., on Thursday released CafeFS 3, a virtualized file system for shared hosters that cages each customer within its own virtualized file system. CageFS becomes part of CloudLinux OS at no additional charge. CloudLinux OS, the only commercially-supported Linux OS m...
    Subscribe to the World's Most Powerful Newsletters
    Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
    Click to Add our RSS Feeds to the Service of Your Choice:
    Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
    myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
    Publish Your Article! Please send it to editorial(at)sys-con.com!

    Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021

    SYS-CON Featured Whitepapers
    ADS BY GOOGLE

    Breaking Cloud Computing News

    The Khronos™ Group, an industry consortium creating open standards for the accelera...