The Basics of Designing a JavaBean

   

All good programmers recognize the importance of the design phase in programming. Thus, you'll start out by addressing how to design a Bean. As you will learn later, the way in which you design your Bean directly affects the way it behaves in containers. For example, the names you choose for the methods should follow specific design specifications. If you start from the beginning with these rules in mind, allowing your Bean to participate in introspection does not require any additional programming on your part. The concept of introspection was introduced in Chapter 28, "Reflection," but you'll see more of how it relates to JavaBeans a little later.

Designing a Bean consists of the following steps:

  1. Specifying the Bean's properties

  2. Specifying the events the Bean generates or responds to

  3. Defining which properties, methods, and events the Bean exposes to other Beans or to its container

  4. Deciding miscellaneous issues, such as whether the Bean has its own Customization dialog box or whether it requires some prototypical state information

You'll start by designing some Beans. For the sake of a simple example, assume that you are developing two Beans; one Bean allows text to be entered into it, and the other displays some text. You can imagine how these Beans might be useful. By placing these two Beans into a container, you can use one to enter text that the other will then display. What types of properties do you think these Beans need to have? What events are these Beans interested in hearing about? What events do these Beans generate? Do these Beans expose all their properties and events, or just some? At this point, you might not know the answers to these questions. The process is the important concept here; the details will become clearer as you progress through the chapter. Regardless, the first thing any Bean needs is a name . In this chapter, the sample Beans will be called TextDisplayer and TextReader.

Specifying the Bean's Properties

The TextDisplayer and TextReader Beans definitely need to have a property defining the text they hold. For example, say that the TextDisplayer Bean also contains properties defining the background color, font, and font color . The TextReader Bean also contains a pro-perty that defines how many columns of characters it can display. Table 29.1 lists the TextDisplayer Bean's properties and the Java types that will be used to implement them. Table 29.2 lists the TextReader Bean's properties and the Java types that will be used for them.

Table 29.1. The TextDisplayer Bean's Properties and Java Types
Property Name Java Type
OutputText java.lang.String
BGColor java.awt.Color
TextFont java.awt.Font
FontColor java.awt.Color
Table 29.2. The TextReader Bean's Properties and Java Types
Property Name Java Type
InputText java.lang.String
Width int

Specifying the Events the Bean Generates or Responds To

The TextDisplayer Bean must respond to an event specifying that its text should change. Specifically, it must update its OutputText property and redraw itself. The TextReader Bean doesn't need to respond to any events, but it must generate (or fire) an event when the user changes its InputText property. This type of event is called a PropertyChangeEvent, for obvious reasons.

Properties, Methods, and Event Exposure

Because these Beans are particularly simple, you don't need to hide anything from the Beans'container or the other Beans interested in them. JavaBeans provides a mechanism for you that will use the names of your methods to extract the names and types of your properties and events. Rest assured that you will learn how this works as you go along. Later in the chapter, you'll learn how to explicitly define what information in a Bean is exposed to its environment.

Initial Property Values and Bean Customizers

To keep this example simple, assume that your Beans do not need any prototypical information (you'll define default values for all their properties) and that they do not have their own Customization dialog box. This means that your Beans have a predefined state when they're instantiated and that they use the standard PropertyEditor s for their properties. If you were designing a Bean that displays an HTML page, for example, specifying default values might not be possible. You would need to know what file to display when the Bean is instantiated. Table 29.3 shows your TextDisplayer Bean's properties and the default values it will hold. Likewise, Table 29.4 is for the TextReader Bean.

Table 29.3. Default Property Values for the TextDisplayer Bean
Property Name Default Value
OutputText "TextDisplayer"
BGColor java.awt.Color.white
TextFont Courier, normal, 12
FontColor java.awt.Color.black
Table 29.4. Default Property Values for the TextReader Bean
Property Name Default Value
InputText "" (an empty string)
Width 40

At this point, you've designed your Beans enough to begin coding. This will be an additive process because you haven't learned how to make the Beans do anything yet. You'll see the relevant pieces of code as you build the example. In Figure 29.1, you can see your Beans hard at work inside the BeanBox. The BeanBox is a JavaBeans container that you can download from Sun's Web site; it's included in the BDK, or Beans Development Kit.

Figure 29.1. Sun's BeanBox shows the TextDisplayer and TextReader Beans.

graphics/29fig01.gif

Right now, the Beans are completely isolated. Because you haven't given the Beans any functionality yet, this is about as good as it gets. The preliminary code needed to instantiate and draw the TextDisplayer Bean is shown in Listing 29.1. Notice that there is no class hierarchy required for a Bean. It is not necessary for a Bean to extend any particular superclass, although it must implement the Serializable interface (or extend a class such as Canvas that does).

Listing 29.1 TextDisplayer.java ” Preliminary Code for the TextDisplayer Bean
 import java.awt.*; import java.beans.*; public class TextDisplayer extends Canvas implements PropertyChangeListener {    // default constructor for this Bean. This is the constructor that an    // application builder (such as Visual Basic) would use.    public TextDisplayer() {       this( "TextDisplayer", Color.white,             new Font( "Courier", Font.PLAIN, 12 ),             Color.black );    }    // custom constructor for this Bean. This is the constructor you would    // likely use if you were going to do all your coding from scratch.    public TextDisplayer( String OutputText, Color BGColor, Font TextFont,                          Color FontColor ) {       this.OutputText = OutputText;       this.BGColor = BGColor;       this.TextFont = TextFont;       this.FontColor = FontColor;       setFont( TextFont );        // set the Canvas's font.       setBackground( BGColor );   // set the Canvas's background color.       setForeground( FontColor ); // set the Canvas's foreground color.    }    // this Bean's properties.    protected String OutputText;    protected Color BGColor, FontColor;    protected Font TextFont;    // override the Canvas's paint method to display the text    public void paint( Graphics g ) {      // simplistic implementation to display a string      g.drawString( OutputText, 10, 20 );    }    // implement the PropertyChangeListener interface    public void propertyChange( PropertyChangeEvent evt ) {      // add code here to respond to a change in a bound property    } } 

The draw method implementation in Listing 29.1 is obviously not as robust as you would want for a reusable component, but it's adequate for demonstrating how the Bean works. You might have also noticed that you have specified that your Bean implement an interface called PropertyChangeListener. This is so that the TextDisplayer Bean can update its OutputText property by receiving an event through its propertyChange method. How that works will be discussed in more detail later in the chapter. The preliminary code needed to instantiate your TextReader Bean is shown in Listing 29.2.

Listing 29.2 TextReader.java ” Preliminary Code for the TextReader Bean
 import java.awt.*; import java.awt.event*; import java.beans.*; public class TextReader extends TextField {    // default constructor for this Bean. This is the constructor that an    // application builder (such as Visual Basic) would use.    public TextReader() {       this( "", 40 );    }    // custom constructor for this Bean. This is the constructor that you    // would likely use if you were doing your coding from scratch.    public TextReader( String InputText, int Width ) {       super( InputText, Width );       this.InputText = InputText;       this.Width = Width;       setEditable( true );       // update the InputText property when the enter key is       // pressed within the TextField       this.addActionListener( new ActionListener() {         public void actionPerformed( ActionEvent e ) {           setInputText(getText());         }       } );    }    // this Bean's properties.    protected String InputText;    protected int Width;    // getter method for the InputText property.    public synchronized String getInputText() {      return InputText;    }    // setter method for the InputText property.    public synchronized void setInputText( String newText ) {       String oldText = InputText;       InputText = newText;       setText( InputText ); // uncomment this statement after the Listing 29.4 additions are made //    changeAgent.firePropertyChange( "inputText", new String( oldText ), //                                    new String( newText ) ); } 
   


Special Edition Using Java 2 Standard Edition
Special Edition Using Java 2, Standard Edition (Special Edition Using...)
ISBN: 0789724685
EAN: 2147483647
Year: 1999
Pages: 353

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net