[ Team LiB ] Previous Section Next Section

15.3 A More Complex Bean

Example 15-3 shows another bean, YesNoPanel. This bean displays a message (using MultiLineLabel) and three buttons to the user. It fires an event when the user clicks on one of the buttons. YesNoPanel is intended for use within dialog boxes, as it provides an ideal way to ask the user yes/no/cancel questions. Figure 15-1 shows a YesNoPanel instance being edited with the ShowBean program.

Figure 15-1. The YesNoPanel bean in a beanbox

The YesNoPanel bean uses a custom AnswerEvent type to notify AnswerListener objects when the user has clicked on one of its three buttons. This new event class and listener interface are defined in the next section.

Notice that YesNoPanel doesn't use any classes from the java.beans package. One of the surprising things about beans is that they typically don't have to use any classes from this package. As you'll see later in this chapter, it's the auxiliary classes that are shipped with a bean that make heavy use of that package.

Example 15-3. YesNoPanel.java
package je3.beans;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.List;
import java.util.ArrayList;

 * This JavaBean displays a multi-line message and up to three buttons.  It
 * fires an AnswerEvent when the user clicks on one of the buttons
public class YesNoPanel extends JPanel {
    // Properties of the bean.
    protected String messageText;  // The message to display
    protected Alignment alignment; // The alignment of the message
    protected String yesLabel;     // Text for the yes, no, & cancel buttons
    protected String noLabel;
    protected String cancelLabel;
    // Internal components of the panel
    protected MultiLineLabel message;
    protected JPanel buttonbox;
    protected JButton yes, no, cancel;
    /** The no-argument bean constructor, with default property values */
    public YesNoPanel( ) { this("Your\nMessage\nHere"); }

    public YesNoPanel(String messageText) { 
        this(messageText, Alignment.LEFT, "Yes", "No", "Cancel");
    /** A constructor for programmers using this class "by hand" */
    public YesNoPanel(String messageText, Alignment alignment,
                      String yesLabel, String noLabel, String cancelLabel) 
        // Create the components for this panel
        setLayout(new BorderLayout(15, 15));
        // Put the message label in the middle of the window.
        message = new MultiLineLabel(messageText, 20, 20, alignment);
        message.setOpaque(false);  // allow background color to show through
        add(message, BorderLayout.CENTER);
        // Create a panel for the Panel buttons and put it at the bottom
        // of the Panel.  Specify a FlowLayout layout manager for it.
        buttonbox = new JPanel( );
        buttonbox.setLayout(new FlowLayout(FlowLayout.CENTER, 25, 15));
        buttonbox.setOpaque(false);  // allow background color to show through
        add(buttonbox, BorderLayout.SOUTH);
        // Create each specified button, specifying the action listener
        // and action command for each, and adding them to the buttonbox
        yes = new JButton( );                   // Create buttons
        no = new JButton( );
        cancel = new JButton( );
        // Add the buttons to the button box

        // Register listeners for each button
        yes.addActionListener(new ActionListener( ) {
                public void actionPerformed(ActionEvent e) {
                    fireEvent(new AnswerEvent(YesNoPanel.this,

        no.addActionListener(new ActionListener( ) { 
                public void actionPerformed(ActionEvent e) {
                    fireEvent(new AnswerEvent(YesNoPanel.this,
        cancel.addActionListener(new ActionListener( ) { 
                public void actionPerformed(ActionEvent e) {
                    fireEvent(new AnswerEvent(YesNoPanel.this,
        // Now call property setter methods to set the message and button
        // components to contain the right text
    // Methods to query all of the bean properties.
    public String getMessageText( ) { return messageText; }
    public Alignment getAlignment( ) { return alignment; }
    public String getYesLabel( ) { return yesLabel; }
    public String getNoLabel( ) { return noLabel; }
    public String getCancelLabel( ) { return cancelLabel; }
    public Font getMessageFont( ) { return message.getFont( ); }
    public Color getMessageColor( ) { return message.getForeground( ); }
    public Font getButtonFont( ) { return yes.getFont( ); }
    // Methods to set all of the bean properties.
    public void setMessageText(String messageText) {
        this.messageText = messageText;

    public void setAlignment(Alignment alignment) {
        this.alignment = alignment;

    public void setYesLabel(String l) {
        yesLabel = l;
        yes.setVisible((l != null) && (l.length( ) > 0));

    public void setNoLabel(String l) {
        noLabel = l;
        no.setVisible((l != null) && (l.length( ) > 0));

    public void setCancelLabel(String l) {
        cancelLabel = l;
        cancel.setVisible((l != null) && (l.length( ) > 0));

    public void setMessageFont(Font f) {
    public void setMessageColor(Color c) {
    public void setButtonFont(Font f) {

    /** This field holds a list of registered ActionListeners. */
    protected List listeners = new ArrayList( );
    /** Register an action listener to be notified when a button is pressed */
    public void addAnswerListener(AnswerListener l) { listeners.add(l); }
    /** Remove an Answer listener from our list of interested listeners */
    public void removeAnswerListener(AnswerListener l) { listeners.remove(l); }
    /** Send an event to all registered listeners */
    public void fireEvent(AnswerEvent e) {
        // Make a copy of the list and fire the events using that copy.
        // This means that listeners can be added or removed from the original
        // list in response to this event.
        Object[  ] copy = listeners.toArray( );
        for(int i = 0; i < copy.length; i++) {
            AnswerListener listener = (AnswerListener) copy[i];
            switch(e.getID( )) {
            case AnswerEvent.YES: listener.yes(e); break;
            case AnswerEvent.NO:  listener.no(e); break;
            case AnswerEvent.CANCEL: listener.cancel(e); break;
    /** A main method that demonstrates the class */
    public static void main(String[  ] args) {
        // Create an instance of YesNoPanel, with title and message specified:
        YesNoPanel p = new YesNoPanel("Do you really want to quit?");

        // Register an action listener for the Panel.  This one just prints
        // the results out to the console.
        p.addAnswerListener(new AnswerListener( ) {
                public void yes(AnswerEvent e) { System.exit(0); }
                public void no(AnswerEvent e) { System.out.println("No"); }
                public void cancel(AnswerEvent e) {
        JFrame f = new JFrame( );
        f.getContentPane( ).add(p);
        f.pack( );
    [ Team LiB ] Previous Section Next Section