This chapter covers these topics:
At its simplest, a JavaBean is a public Java class that has a constructor with no parameters. JavaBeans usually have properties, methods, and events that follow certain naming conventions (also known as design patterns).
You use the JavaBean Wizard to specify the name of your bean, the package it will be in, and the class it extends.
Within the JavaBean Wizard,
By default, this will be the name of your current project.
The drop-down list presents a list of convenient classes to use for constructing a new JavaBean. You can use one of these classes, or you can click the adjacent button to display the Package browser and use it to specify any existing Java class you want.
If you want only core JDK and Swing components to display in the drop-down list, check the Show Only Core JDK and Swing Classes option below the list.
To read about the types of classes convenient to use as a starting point for a new JavaBean and to help you choose the class you need, see Creating original components.
You might want this for your first bean to see how JBuilder generates the required code for a property. You can remove this property later, or make it an actual property that your bean can use.
JBuilder creates a JavaBean with the name you specified, places it in your current project, and displays the source code it generated. This is the code JBuilder generates for the settings shown here:
package beans; import java.awt.*; import borland.jbcl.view.BeanPanel; public class BeanieBaby extends BeanPanel { BorderLayout borderLayout1 = new BorderLayout(); public BeanieBaby() { try { jbInit(); } catch (Exception e) { e.printStackTrace(); } } void jbInit() throws Exception( this.setLayout(borderLayout1); } }If you examine the code JBuilder generated, you’ll note that:
Even in this rudimentary state, your class is a valid JavaBean.
To create a user interface for your bean,
For information on creating a user interface, see Designing a user interface.
JavaBeans properties usually have both a read and a write access method, also known as a getter and a setter, respectively. A getter method returns the current value of the property; a setter method sets the property to a new value.
To add a property to your bean,
The New Property dialog box appears.
You can type in one of the Java types or use the Package browser to select any object type, including other JavaBeans.
If you want to make a property read-only, uncheck the Setter check box.
JBuilder generates the necessary code for the property and adds the property to the Properties Designer grid. You can see the read and write access methods added to the Component Tree for your bean. If you click the Source tab, you can see the code JBuilder generated.
Here is the New Property dialog box with all the required fields filled in:
The Display Name and Short Description are filled in automatically with default values. This is the resulting source code:
package beans; import java.awt.*; import borland.jbcl.view.BeanPanel; public class BeanieBaby extends BeanPanel { BorderLayout borderLayout1 = new BorderLayout(); private float price; // Added a private price field public BeanieBaby() { try { jbInit(); } catch (Exception e) { e.printStackTrace(); } } void jbInit() throws Exception( this.setLayout(borderLayout1); } public void setPrice(float newPrice) { // Added a method to change the price value price = newPrice; } public float getPrice() { // Added a method to obtain the price value return price; } }
JBuilder added a private price field to the BeanieBaby class. The price field holds the value of the property. Usually a property field should be declared as private so that only the getter and setter methods can access the field.
It also generated a setPrice() method that can change the value of the new field, and it generated a getPrice() method that can get the current value of the field.
When your bean is installed on JBuilder’s Component Palette and users drop the bean on the UI Designer, the price property will appear in the Component Inspector so that users can modify its value. All the code to get and set the price property is in place.
For more information about declaring properties in JavaBeans and the read and write access methods, see Defining simple properties in the Component Writer’s Guide.
To modify a property,
For example, you can change the type of the property by entering another type.
JBuilder reflects the changes you make in the Properties Designer in the source code of your bean. You can also make changes directly in the source code and the BeansExpress designers will reflect the changes if the changes have been made correctly.
To remove a property from your bean,
The property field and its access methods are removed from the source code.
To add a bound or constrained property,
If the property you added is a bound property, JBuilder adds the private property field to the class and generates its read and write methods. It also instantiates an instance of the PropertyChangeSupport class. For example, here is the code added for a bound property called allTiedUp:
public class BeanieBaby extends BeanPanel { ... private String allTiedUp; private transient PropertyChangeSupport propertyChangeListeners = new PropertyChangeSupport(this); ... public void setAllTiedUp(String newAllTiedUp) { String oldAllTiedUp = allTiedUp; allTiedUp = newAllTiedUp; propertyChangeListeners.firePropertyChange("allTiedUp", oldAllTiedUp, newAllTiedUp); } public String getAllTiedUp() { return allTiedUp; }
Note that the setAllTiedUp() method includes the code to notify all listening components of changes in the property value.
JBuilder also generates the event-listener registration methods that are called by listening components that want to be notified when the property value of allTiedUp changes:
public synchronized void removePropertyChangeListener(PropertyChangeListener listener) { propertyChangeListeners.removePropertyChangeListener(listener); } public synchronized void addPropertyChangeListener(PropertyChangeListener listener) { propertyChangeListeners.addPropertyChangeListener(listener); }
The code JBuilder generates for a constrained property is similar except the listeners have the opportunity to reject the change in property value. To read about bound and constrained properties, see Defining bound properties and Defining constrained properties in the Component Writer’s Guide. To learn about events and listeners for events, see Working with events in the Component Writer’s Guide.
BeanInfo classes are optional. You can use BeansExpress to generate a BeanInfo class for you to customize your bean. If you are going to use a BeanInfo class, you should specify more detailed information for each new property you add to your bean.
To hide a property so it does not appear in visual design tools such as JBuilder’s Component Inspector, make sure the Expose through BeanInfo option is unchecked.
To provide a localized display name for this property, enter the property name you want to use in the Display Name field.
To provide a short description of this property, enter the description in the Short Description field. JBuilder displays this text as a tool tip in the Component Inspector for this property.
If you have created a property editor that can edit this field, specify the property editor in the Editor field. The Editor field displays all editors in scope that match the given property type.
For more information about property editors, see Creating a property editor.
The BeanInfo Designer displays all the properties you have added to your bean. If you change your mind about the BeanInfo data you entered for a property, you can edit one or more of these fields in the grid. Only the name of the property can’t be changed.
To provide an image to use as an icon to represent your bean, specify one or more images in the Icons boxes.
The Icon boxes let you specify different icons to use for both color and mono environments and for different screen resolutions. Fill in the boxes that meet your needs.
If the superclass of your bean has a BeanInfo class and you want its BeanInfo data exposed in the BeanInfo class for your bean, check the Expose Superclass BeanInfo check box. The generated code will include a getAdditionalBeanInfo() method that returns the BeanInfo data of the class your bean extends.
To generate a BeanInfo class for your bean, click the Generate Bean Info button.
JBuilder creates a BeanInfo class for you. You’ll see it appear in the Navigation pane. To see the generated code, select the new BeanInfo class in the Navigation pane and the source code appears.
You are warned that you are about to overwrite the existing BeanInfo class. If you choose OK, the class is overwritten with the new BeanInfo data.
For more information on BeanInfo classes, see Specifying component information with BeanInfo classes in the Component Writer’s Guide.
BeansExpress can generate the code that makes your bean capable of doing one or both of these things. To read about events, see Working with events in the Component Writer’s Guide.
The Events Designer adds the event-registration methods to your bean. These methods are called by components that want to be notified when these types of events occur. For example, if you select Key events, these methods are added to your bean:
package myBeans; import java.awt.*; import borland.jbcl.view.BeanPanel; import java.awt.event.*; import java.util.*; public class BeanieBaby extends Beanpanel { public BeanieBaby() { } private transient Vector keyListeners; public synchronized void addKeyListener(KeyListener l) { Vector v = keyListeners == null ? new Vector(2) : (Vector) keyListeners.clone(); if (!v.contains(l)) { v.addElement(l); keyListeners = v; } } public synchronized void removeKeyListener(KeyListener l) { if KeyListeners != null && keyListeners.contains(l)) { Vector v = (Vector) keyListeners.clone(); v.removeElement(l); keyListeners = v; } }When a component wants to be notified of a key event occurring in your bean, it calls the addKeyListener() method of your bean and that component is added as an element in KeyListeners. When a key event occurs in your bean, all listening components stored in KeyListeners are notified.
The class also generates fire<event> methods that send an event to all registered listeners. One such event is generated for each method in the Listener’s interface. For example, the KeyListener interface has three methods: keyTyped(), keyPressed(), and keyReleased(). So the Events Designer adds these three fire<event> methods to your bean class:
protected void fireKeyTyped(KeyEvent e) { if (keyListeners != null) { Vector listeners = keyListeners; int count = listeners.size(); for (int i = 0; i < count; i++) ((KeyListener) listeners.elementAt(i)).keyTyped(e); } } protected void fireKeyPressed(KeyEvent e) { if (keyListeners != null) { Vector listeners = keyListeners; int count = listeners.size(); for (int i = 0; i < count; i++) ((KeyListener) listeners.elementAt(i)).keyPressed(e); } } protected void fireKeyReleased(KeyEvent e) { if (keyListeners != null) { Vector listeners = keyListeners; int count = listeners.size(); for (int i = 0; i < count; i++) ((KeyListener) listeners.elementAt(i)).keyReleased(e); } }Once you’ve made your bean capable of generating events, those events will appear in JBuilder’s Component Inspector when the user drops your bean on the UI Designer.
To make your bean a listener, select one of the event types to listen for in the Events Designer.
As soon as you check one of the event types, the Events Designer implements the associated listener interface in your bean. For example, if you checked java.awt.event.KeyListener, the phrase implements KeyListener is added to the declaration of your bean and the KeyPressed(), KeyReleased(), and KeyTyped() methods are implemented with empty bodies. Here is a bean that includes the generated code to implement the KeyListener interface:
package myBeans; import java.awt.*; import com.sun.java.swing.JPanel; import java.awt.event.*; public class JellyBean extends JPanel implements KeyListener { // implements KeyListener BorderLayout borderLayout1 = new BorderLayout(); public JellyBean() { try { jbInit(); } catch (Exception e) { e.printStackTrace(); } } void jbInit() throws Exception { this.setLayout (borderLayout1); } public void keyTyped(KeyEvent parm1) { // Adds new method } public void keyPressed(KeyEvent parm1) { // Adds new method } public void keyReleased(KeyEvent parm1) { // Adds new method } }
If your bean is registered with another component as a listener (by calling the event-registration method of the component), the source component calls one of the methods in the listening component when that type of event occurs. For example, if a KeyPressed event occurs in the source component, the KeyPressed() method is called in the listening component. Therefore, if you want your component to respond in some way to such an event, write the code that responds within the body of the KeyPressed() method, for example.
For more information on generating and listening for events, see Working with events in the Component Writer’s Guide.
To create a custom event set,
The New Event Type dialog box appears.
The names of the event object and the event listener are generated from the name of the event set; they are displayed in the dialog box.
The new event set is added to list of event types that can be fired in the Events Designer.
JBuilder generates the event object class for the event set:
package myBeans; import java.util.*; public class PasswordEvent extends EventObject { public PasswordEvent(Object source) { super(source); } }JBuilder also generates the Listener interface for the event set:
package myBeans; import java.util.*; public interface PasswordListener extends EventListener { public void passwordSuccessful(PasswordEvent e); public void passwordFailed(PasswordEvent e); }For more information on events sets and creating new ones, see Working with events in the Component Writer’s Guide.