Contents
This document
What is JBeans?
Why use JBeans?
What does JBeans replace?
Making life easier
Installation
Building
Case studies/scenarios
First steps/definitions
Using BeanProperty
Using IndexedBeanProperty
Using NestedBeanProperty
Using DynamicNestedBeanProperty
Using JavaBean
Events and conversion
Conversion

This section will start off with an overview of the converter scheme for the JBeans package and then move on to events.

Conversion (or from the definition section, auto-conversion) occurs when properties are being changed and the type of the new value is not the correct type for the set method. For example, if we are trying to change the value of a property called age, which is of type int, and we pass it the string 42 as a String object. Obviously the value of the string is a proper integer, but you can't just cast a string to an int (at least in Java :). So, what you do is ask the BeanProperty (or which ever class you are using) to auto-convert the value for you. Here's an example using the BeanProperty class:

    /* We'll use this JavaBean for our example */
    public class User {
        private int age;
        
        public int getAge() { return age; }
        public void setAge(int value) { age = value; }
    }
    
    // Auto-conversion
    User userInstance = new User();
    
    try {
        BeanProperty property = new BeanProperty("age", User.class);
        property.setPropertyValue(userInstance, "42", true); 
        System.out.println("The user's age: " + user.getAge());
    } catch (BeanException be) {
        be.printStackTrace();
    }
    
    /*
    Output:
    The user's age: 42
    */
    

A few things to notice about this example. First, when we called the setPropertyValue method we used the version that takes a third parameter which tells the method whether or not to convert the parameter (if necessary). Second, when conversion fails, a TypeConversionException is thrown. This exception is a sub-class of BeanException and therefore is caught by out catch block.

But there it is. Very simple indeed. Okay, you're dying to know how it works right? Well, here's the skinny. The setPropertyValue method determines what the type of the property that is being set is. If the new value is not of the same type or a sub-class of the type, auto-conversion happens. If it is of the same type or sub-class, no conversion occurs. The way that the actual conversion occurs is that the TypeConverterManager is consult to determine if a converter exists for the type of the property (in our case Integer.TYPE). If there is one, it is retrieved and the convert method is called on it to do the actual conversion.

Although it is important to know how to implement new converters, it is a fairly simple process and we will only go over it very briefly here. You must implement the org.jbeans.TypeConverter interface. You can extend the org.jbeans.BaseTypeConverter class, which is an excellent starting point. After you have completed writing the class, you application must register it with the TypeConverterManager using the registerTypeConverter method. Most of the rest of it is explained thoroughly in the Javadocs for the TypeConverter, BaseTypeConverter and TypeConverterManager.

One last note before moving on. The TypeConverter interface is very powerful and handles all types of conversions including conversions to and from arrays. JBeans supports all of these conversion. That is to say, if you have a property which is an array type, you can convert a String into an instance of the array type. For example, you can convert the String "1,2,3,4" to an array of Integer objects. This is done using a delimiter character, tokenizing the string and converting each token into the correct type.

 
Property events

Now, let's move to our last topic, events. Events are a powerful tool used for observing actions that occur on Java bean's via the JBeans package. When a property is accessed using one of the classes in the JBeans package, event listeners get notified of the access. This is done in the standard way that is used throughout the Java APIs, by adding event listeners to the class you are using to access the property. There are two different types of event listeners in the JBeans package, PropertyListener and ConversionListener. The first is notified whenever a property is changed or retrieved. The second is used whenever an auto-conversion takes place. Here are the methods in the PropertyListener interface:

    public void handleGet(PropertyEvent event);
    
    public void handleSet(PropertyEvent event);
    

The first method gets called whenever a property's value is retrieved. The second method gets called whenever a property's value is changed. The PropertyEvent class provides information about the property accessed, the current value of the property, the Java bean instance which the property was accessed on and much more. Here is a simple example to show you how the PropertyListener works:

    /* We'll use this JavaBean for our example */
    public class User {
        private String name;
        
        public String getName() { return name; }
        public void setName(String value) { name = value; }
    }
    
    /* We'll use this PropertyListener for our example */
    public class MyListener implements PropertyListener {
        public void handleGet(PropertyEvent event) {
            System.out.println("The property was retrieved");
        }
    
        public void handleSet(PropertyEvent event) {
            System.out.println("The property was changed");
        }
    }
    
    // Retrieving the property
    User userInstance = new User();
    userInstance.setName("Fred");
    
    try {
        BeanProperty property = new BeanProperty("name", User.class);
        property.addPropertyListener(new MyListener());
        
        // Gets the users name from the userInstance instance of the User class
        String name = (String) property.getPropertyValue(userInstance); 
        System.out.println("The user's name: " + name);
    } catch (BeanException be) {
        be.printStackTrace();
    }
    
    /*
    Output:
    The property was retrieved
    The user's name: Fred
    */
    
    try {
        BeanProperty property = new BeanProperty("name", User.class);
        
        property.addPropertyListener(new MyListener());
        property.setPropertyValue(userInstance, "Wilma"); 
        System.out.println("The user's name: " + user.getName());
    } catch (BeanException be) {
        be.printStackTrace();
    }
    
    /*
    Output:
    The property was changed
    The user's name: Wilma
    */
    

This example doesn't do anything exciting, but it does show how accessing properties causes the events to be generated by the JBeans package and the event listeners to be called.

 
Conversion events

The other type of event is the conversion event. These type of events are generated when auto-conversion takes place while changing property values. The methods in the ConversionListener interface that are called are:

    public void handlePreConversion(ConversionEvent event);
    
    public void handlePostConversion(ConversionEvent event);
    
    public void handleFailedConversion(ConversionEvent event);
    

The first method is called whenever a conversion is about to take place, but before it actually has. The second method is called after a conversion has successfully taken place. The third method is called if the conversion failed for any reason. Here are some simple examples of how the conversion event listeners work.

    /* We'll use this JavaBean for our example */
    public class User {
        private int age;
        
        public int getAge() { return age; }
        public void setAge(int value) { age = value; }
    }
    
    /* We'll use this ConversionListener for our example */
    public class MyListener implements ConversionListener {
        public void handlePreConversion(ConversionEvent event) {
            System.out.println("The conversion is about to happen");
        }
    
        public void handlePostConversion(ConversionEvent event) {
            System.out.println("The conversion was a success");
        }
    
        public void handleFailedConversion(ConversionEvent event) {
            System.out.println("The conversion failed");
        }
    }
    
    // Setting the property to force auto-conversion
    User userInstance = new User();
    
    try {
        BeanProperty property = new BeanProperty("name", User.class);
        property.addConversionListener(new MyListener());

        property.setPropertyValue(userInstance, "42");        
        System.out.println("The user's age: " + user.getAge());
    } catch (BeanException be) {
        be.printStackTrace();
    }
    
    /*
    Output:
    The conversion is about to happen
    The conversion was a success
    The users age: 42
    */
    
    try {
        BeanProperty property = new BeanProperty("name", User.class);
        property.addConversionListener(new MyListener());

        property.setPropertyValue(userInstance, "NOT A NUMBER");        
    } catch (BeanException be) {
        System.out.println("The user's age was not set");
    }
    
    /*
    Output:
    The conversion is about to happen
    The conversion failed
    The users age was not set
    */
    

As you can see, depending on the conversion, the different methods in the ConversionListener interface and called automatically by the JBeans package classes.

These event examples only use the BeanProperty class, but events can be used on the IndexedBeanProperty and NestedBeanProperty classes as well. If you would like anymore information about the event listener interfaces or the event classes (PropertyEvent or ConversionEvent), please consult the Javadocs for the JBean package.