## SimpleAbleBean - How to create a custom AbleBean

This example shows the easiest method for creating a custom AbleBean, by extending the AbleObject base class.

There are three java parts that must be created for any AbleBean:

1. The bean class file (SimpleAbleBean.java)
2. The bean info file (SimpleAbleBeanInfo.java)
3. The bean customizer file (SimpleAbleBeanCustomizer.java)

To see how the SimpleAbleBean works, go to the Samples panel on the icon palette. Move the mouse slowly over each icon and a tooltip text window will display the name of the bean. Click on the icon for the "SimpleBean". This will create an instance and place it on the canvas.

To see what is going on in the bean, right click to bring up a context (popup) menu. Select "Inspect" to open an Inspector window. This will show inputBuffer and outputBuffer as null. Move the Inspector window off to the side. Now bring up the context menu again and select "Settings". This will open a customizer dialog for the simple bean. Enter a string value for the color property, say "Blue", and click on OK to close the dialog. We just set the simpleBeanColor property value. Now to move the value to the outputBuffer, either click on the Step button on the top left, or select "Process" from the context menu. This will cause the process() method to be called, and the contents of the simpleBeanColor property to be placed in the outputBuffer. You should see the string you entered in the Customizer dialog appear in the Inspector window display.

Each time you open the customizer and enter a new Color value and then do a process() on the bean, the string will be moved to the outputBuffer. To see some other interesting behavior of this bean, go to the SimpleAbleAgent example.

### Bean class file (SimpleAbleBean.java)

The easiest way to create a JavaBean that implements the AbleBean interface is to extend the AbleObject base class, which is what our SimpleAbleBean does. AbleObject is used as the base implementation class for all of the core AbleBeans such as AbleImport as well as the function-specific beans such as AbleNeuralClassifier. In addition to providing concrete implementations for all AbleBean methods, AbleObject also implements the AbleEventListener methods, and is fully remotable using RMI (AbleObject extends UnicastRemoteObject).

We will inherit most of the behavior provided by the AbleObject base class. This includes getter/setter methods for most of the attributes, support for BufferConnections, PropertyConnections, and EventConnections. We will focus on only those things required to add specialized processing functions to a standard AbleBean.

#### Class Imports

Specify the following imports:

>     import java.rmi.*;
>     import java.io.*;
>     import com.ibm.able.*;

We need to import the java.io. package to pick up the Serializable interface, required so we can save and load the bean from the Able Editor using Import/Export bean under the File menu.

#### Class Methods

Any bean that extends AbleObject should provide its own implementation of the follow methods:

- Constructor
- init
- reset
- process

#### Constructor method

> First create a default zero-parameter constructor (which is a requirement for any JavaBean). Because we are extending AbleObject which is a remote object, we must add the "throws RemoteException" clause to the constructor. In this simple example, the constructor sets the bean name and then just calls the init() method.

> >       public SimpleAbleBean() throws RemoteException {
> >         super("SimpleBean");
> >         init();
> >       }

init()

> This method will initialize any local data members and resources. It also specifies the behavior of the AbleEventQueue which is contained by the bean. The event queue supports timed events and asynchronous event processing running on its own thread. In this example, we do not use either of these capabilities and we do not create the event queue thread.

> Since we want to support data flow using BufferConnections, we must allocate the inputBuffer and outputBuffer arrays. Currently, Able supports either String[] buffers (for alpha or mixed alpha and numeric data) or double[] buffers (for all numeric data). In most cases the size of these buffers is dependent on user configuration data or parameters and so the buffers are dynamically allocated in the init() or reset() methods. Our bean will have only one value, a String denoting its color.

> >       public void init() throws RemoteException {
> >         // need to allocate the input and output buffers here (if used)
> >            inputBuffer = new String[1] ;
> >            outputBuffer = new String[1] ;
> >            simpleBeanColor = "magenta" ;
> >            setDataFlowEnabled(true) ;
> >           // No timer processing, and no asynch events
> >            setSleepTime(0);
> >            setTimerEventProcessingEnabled(false);
> >            setAbleEventProcessingEnabled(Able.ProcessingDisabled_PostingDisabled);
> >           // Note: we don't create an event queue thread
> >       }

reset()

> This method will reset the bean to a known state. For example, in neural networks, this method would typically reset the network weights and training parameters.

> >       public void reset() throws RemoteException {
> >         init() ; // re-allocate the input buffers
> >       }

process()

This is the main processing method where the bean does its stuff. For beans that support buffer connections, a processConnections() call is done here to move the source data into the inputBuffer. Next the bean would process the input data and place the results in the outputBuffer. If buffer connections are not supported or used, then the bean could get its input data through events, property connections or a sensor named as a user-defined function. After processing it, the results would be passed via property connections, events, or an effector named as a user-defined function. A dataChanged() call at the end of process signals other beans and any open Inspectors that the bean has changed.

>       public void process() throws RemoteException {
>         processBufferConnections() ;   // move data into inputBuffer (if any)

>         // perform the main processing here
>         Object in = getInputBuffer(0) ;  // see if there is data in the input buffer
>         if (in != null) {
>           simpleBeanColor = (String)getInputBuffer(0) ; // copy to the color parameter
>         }
>         // Note: we either process data in the input buffer
>         //       or use other data member values as inputs

>         // assign output data to the outputBuffer here
>         setOutputBuffer(0, simpleBeanColor) ;

>         dataChanged(this) ;  // tell any AbleEventListeners that we changed
>       }

### Bean Info file (SimpleAbleBeanBeanInfo.java)

The bean info file contains information about the properties and methods supported by the bean. There are a couple of bean attributes used by the Able Editor to position the beans on the icon palette ("able-category") and on the canvas ("able-slot"). The bean info file specifies the name of the bean class itself, the customizer class, and the icon (*.gif) files. The methods are similar to SimpleAbleAgentBeanInfo.

### Bean Customizer (SimpleAbleBeanCustomizer.java)

The easiest way to create a customizer for any bean is to extend the customizer that its bean extends, in this case AbleObjectCustomizer. Since the SimpleAbleBean extends AbleObject, extending that customizer allows you to inherit panels and controls that can change properties of the AbleObject. The SimpleAbleBeanCustomizer then has only to create and manage a panel for data specific to the SimpleAbleBean. Generally a customizer must be a subclass of the awt Component class. In the Able environment which is based on the Swing GUI library, we support JPanel, JDialog, and JFrame. A customizer that is a subclass of JDialog or JFrame will be instantiated and then opened using the show() method. Simple beans will typically extend one of the provided customizers, while more complex beans will extend JPanel directly or may require complex dialogs or even full-blown editor windows with menu bars and icon palettes.

In the SimpleAbleBean customizer, we extend the AbleObjectCustomizer, and show how you can support a text field name for the bean's color value.