Java/Language Basics/Java Beans

Материал из Java эксперт
Перейти к: навигация, поиск

A JTable subclass that displays a table of the JavaBeans properties of any specified class

 
 
 
/*
 * Copyright (c) 2004 David Flanagan.  All rights reserved.
 * This code is from the book Java Examples in a Nutshell, 3nd Edition.
 * It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.
 * You may study, use, and modify it for any non-commercial purpose,
 * including teaching and use in open-source projects.
 * You may distribute it non-commercially as long as you retain this notice.
 * For a commercial use license, or to purchase the book, 
 * please visit http://www.davidflanagan.ru/javaexamples3.
 */
//package je3.gui;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.Arrays;
import java.util.ruparator;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
/**
 * This class is a JTable subclass that displays a table of the JavaBeans
 * properties of any specified class.
 */
public class PropertyTableJavaBean extends JTable {
  /** This main method allows the class to be demonstrated standalone */
  public static void main(String[] args) {
    // Specify the name of the class as a command-line argument
    Class beanClass = null;
    try {
      // Use reflection to get the Class from the classname
      beanClass = new JButton().getClass();
    } catch (Exception e) { // Report errors
      System.out.println("Can"t find specified class: " + e.getMessage());
      System.out.println("Usage: java PropertyTableJavaBean <bean class name>");
      System.exit(0);
    }
    // Create a table to display the properties of the specified class
    JTable table = new PropertyTableJavaBean(beanClass);
    // Then put the table in a scrolling window, put the scrolling
    // window into a frame, and pop it all up on to the screen
    JScrollPane scrollpane = new JScrollPane(table);
    JFrame frame = new JFrame("Properties of JavaBean: ");
    frame.getContentPane().add(scrollpane);
    frame.setSize(500, 400);
    frame.setVisible(true);
  }
  /**
   * This constructor method specifies what data the table will display (the
   * table model) and uses the TableColumnModel to customize the way that the
   * table displays it. The hard work is done by the TableModel implementation
   * below.
   */
  public PropertyTableJavaBean(Class beanClass) {
    // Set the data model for this table
    try {
      setModel(new JavaBeanPropertyTableModel(beanClass));
    } catch (IntrospectionException e) {
      System.err.println("WARNING: can"t introspect: " + beanClass);
    }
    // Tweak the appearance of the table by manipulating its column model
    TableColumnModel colmodel = getColumnModel();
    // Set column widths
    colmodel.getColumn(0).setPreferredWidth(125);
    colmodel.getColumn(1).setPreferredWidth(200);
    colmodel.getColumn(2).setPreferredWidth(75);
    colmodel.getColumn(3).setPreferredWidth(50);
    // Right justify the text in the first column
    TableColumn namecol = colmodel.getColumn(0);
    DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
    renderer.setHorizontalAlignment(SwingConstants.RIGHT);
    namecol.setCellRenderer(renderer);
  }
  /**
   * This class implements TableModel and represents JavaBeans property data in
   * a way that the JTable component can display. If you"ve got some type of
   * tabular data to display, implement a TableModel class to describe that
   * data, and the JTable component will be able to display it.
   */
  static class JavaBeanPropertyTableModel extends AbstractTableModel {
    PropertyDescriptor[] properties; // The properties to display
    /**
     * The constructor: use the JavaBeans introspector mechanism to get
     * information about all the properties of a bean. Once we"ve got this
     * information, the other methods will interpret it for JTable.
     */
    public JavaBeanPropertyTableModel(Class beanClass) throws java.beans.IntrospectionException {
      // Use the introspector class to get "bean info" about the class.
      BeanInfo beaninfo = Introspector.getBeanInfo(beanClass);
      // Get the property descriptors from that BeanInfo class
      properties = beaninfo.getPropertyDescriptors();
      // Now do a case-insensitive sort by property name
      // The anonymous Comparator implementation specifies how to
      // sort PropertyDescriptor objects by name
      Arrays.sort(properties, new Comparator() {
        public int compare(Object p, Object q) {
          PropertyDescriptor a = (PropertyDescriptor) p;
          PropertyDescriptor b = (PropertyDescriptor) q;
          return a.getName().rupareToIgnoreCase(b.getName());
        }
        public boolean equals(Object o) {
          return o == this;
        }
      });
    }
    // These are the names of the columns represented by this TableModel
    static final String[] columnNames = new String[] { "Name", "Type", "Access", "Bound" };
    // These are the types of the columns represented by this TableModel
    static final Class[] columnTypes = new Class[] { String.class, Class.class, String.class,
        Boolean.class };
    // These simple methods return basic information about the table
    public int getColumnCount() {
      return columnNames.length;
    }
    public int getRowCount() {
      return properties.length;
    }
    public String getColumnName(int column) {
      return columnNames[column];
    }
    public Class getColumnClass(int column) {
      return columnTypes[column];
    }
    /**
     * This method returns the value that appears at the specified row and
     * column of the table
     */
    public Object getValueAt(int row, int column) {
      PropertyDescriptor prop = properties[row];
      switch (column) {
      case 0:
        return prop.getName();
      case 1:
        return prop.getPropertyType();
      case 2:
        return getAccessType(prop);
      case 3:
        return new Boolean(prop.isBound());
      default:
        return null;
      }
    }
    // A helper method called from getValueAt() above
    String getAccessType(PropertyDescriptor prop) {
      java.lang.reflect.Method reader = prop.getReadMethod();
      java.lang.reflect.Method writer = prop.getWriteMethod();
      if ((reader != null) && (writer != null))
        return "Read/Write";
      else if (reader != null)
        return "Read-Only";
      else if (writer != null)
        return "Write-Only";
      else
        return "No Access"; // should never happen
    }
  }
}





BeanContext Child Support

/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
import java.beans.beancontext.BeanContextChildSupport;
import java.beans.beancontext.BeanContextSupport;
/**
 * Test program that adds 100 beans to a context, and calls size() to report the
 * number of beans currently nested. Finally, this test calls toArray() to get
 * references to all child beans.
 */
public class Example2 {
  public static void main(String[] args) {
    // A BeanContext
    BeanContextSupport context = new BeanContextSupport();
    // Many JavaBeans
    BeanContextChildSupport[] beans = new BeanContextChildSupport[100];
    System.out.println("Number of children in the context: " + context.size());
    // Create the beans and add them to the context
    for (int i = 0; i < beans.length; i++) {
      beans[i] = new BeanContextSupport();
      context.add(beans[i]);
    }
    System.out.println("Number of children in the context: " + context.size());
    // Context now has 100 beans in it, get references to them all
    Object[] children = context.toArray();
    System.out.println("Number of objects retrieved from the context: "
        + children.length);
  }
}





BeanContext Support

/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
import java.beans.beancontext.BeanContextChildSupport;
import java.beans.beancontext.BeanContextSupport;
/**
 * A test program that adds a bean to a beancontext, and reports on various
 * aspects of the context"s membership state. This program also shows that a
 * bean"s getBeanContext() method can be called to get a reference to its
 * enclosing context.
 */
public class Example1 {
  private static BeanContextSupport context = new BeanContextSupport(); // The
                                                                        // BeanContext
  private static BeanContextChildSupport bean = new BeanContextChildSupport(); // The
                                                                                // JavaBean
  public static void main(String[] args) {
    report();
    // Add the bean to the context
    System.out.println("Adding bean to context...");
    context.add(bean);
    report();
  }
  private static void report() {
    // Is the context empty?
    System.out.println("Is the context empty? " + context.isEmpty());
    // Has the context been set for the child bean?
    boolean result = (bean.getBeanContext() != null);
    System.out.println("Does the bean have a context yet? " + result);
    // Number of children in the context
    System.out.println("Number of children in the context: " + context.size());
    // Is the specific bean a member of the context?
    System.out.println("Is the bean a member of the context? "
        + context.contains(bean));
    // Equality test
    if (bean.getBeanContext() != null) {
      boolean isEqual = (bean.getBeanContext() == context); // true means both
                                                            // references point
                                                            // to the same
                                                            // object
      System.out.println("Contexts are the same? " + isEqual);
    }
  }
}





Creates all of the objects, a tests the service capabilities

/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
import java.beans.beancontext.BeanContextChildSupport;
import java.beans.beancontext.BeanContextServiceAvailableEvent;
import java.beans.beancontext.BeanContextServiceProvider;
import java.beans.beancontext.BeanContextServiceRevokedEvent;
import java.beans.beancontext.BeanContextServices;
import java.beans.beancontext.BeanContextServicesSupport;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.Iterator;
import java.util.StringTokenizer;
/**
 * A test program that creates all of the objects, a tests the service
 * capabilities. Run this program from the command line using java
 * DocumentTester
 */
public class DocumentTester {
  public static void main(String[] args) {
    BeanContextServicesSupport context = new BeanContextServicesSupport(); // a
                                                                            // bean
                                                                            // context
    DocumentBean doc1 = new DocumentBean("Test.txt");
    context.add(doc1);
    context.addBeanContextServicesListener(doc1); // listen for new services
    WordCountServiceProvider provider = new WordCountServiceProvider();
    context.addService(WordCount.class, provider); // add the service to the
                                                    // context
  }
}
/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc. All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *  - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *  - Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *  - Neither the name of Sun Microsystems nor the names of its contributors may
 * be used to endorse or promote products derived from this software without
 * specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
/**
 * A JavaBean that encapsulates a text file. When added to a bean context, this
 * bean listens for a WordCount service to become available. When the service
 * does become available, the DocumentBean requests an instance of the service.
 * The service then counts the number of words in the file, and prints a report
 * to standard output.
 */
final class DocumentBean extends BeanContextChildSupport {
  private File document;
  private BeanContextServices context;
  /**
   * Creates a new DocumentBean given the name of the file to read from.
   * 
   * @param fileName
   *            the name of the file to read from
   */
  public DocumentBean(String fileName) {
    document = new File(fileName);
  }
  /**
   * Called when this bean detects that a new service has been registered with
   * its context.
   * 
   * @param bcsae
   *            the BeanContextServiceAvailableEvent
   */
  public void serviceAvailable(BeanContextServiceAvailableEvent bcsae) {
    System.out.println("[Detected a service being added to the context]");
    // Get a reference to the context
    BeanContextServices context = bcsae.getSourceAsBeanContextServices();
    System.out.println("Is the context offering a WordCount service? "
        + context.hasService(WordCount.class));
    // Use the service, if it"s available
    if (context.hasService(WordCount.class)) {
      System.out.println("Attempting to use the service...");
      try {
        WordCount service = (WordCount) context.getService(this, this,
            WordCount.class, document, this);
        System.out.println("Got the service!");
        service.countWords();
      } catch (Exception e) {
      }
    }
  }
  /**
   * Called when this bean detects that a service has been revoked from the
   * context.
   * 
   * @param bcsre
   *            the BeanContextServiceRevokedEvent
   */
  public void serviceRevoked(BeanContextServiceRevokedEvent bcsre) {
    System.out.println("[Detected a service being revoked from the context]");
  }
}
/**
 * The WordCount service. Implementations of the countWords() method are
 * provided by the WordCountServiceProvider class.
 */
interface WordCount {
  /**
   * Counts the number of words in the file.
   */
  public abstract void countWords();
}
/**
 * This class is the factory that delivers a word counting service. The 3
 * methods defined in this class are the concrete implementations of the
 * BeanContextServiceProvider interface. For this demonstration, the primary
 * method of interest is getService(). The getService() methods returns a new
 * WordCount instance. It is called by the bean context when a nested JavaBean
 * requests the service.
 */
final class WordCountServiceProvider implements BeanContextServiceProvider {
  public Object getService(BeanContextServices bcs, Object requestor,
      Class serviceClass, Object serviceSelector) {
    // For this demo, we know that the cast from serviceSelector
    // to File will always work.
    final File document = (File) serviceSelector;
    /*
     * Return an instance of the service. The service itself is the WordCount
     * interface, which is implemented here using an anonymous inner class.
     */
    return new WordCount() {
      public void countWords() {
        try {
          // Create a Reader to the DocumentBean"s File
          BufferedReader br = new BufferedReader(new FileReader(document));
          String line = null;
          int wordCount = 0;
          while ((line = br.readLine()) != null) {
            StringTokenizer st = new StringTokenizer(line);
            while (st.hasMoreTokens()) {
              System.out.println("Word " + (++wordCount) + " is: "
                  + st.nextToken());
            }
          }
          System.out.println("Total number of words in the document: "
              + wordCount);
          System.out
              .println("[WordCount service brought to you by WordCountServiceProvider]");
          br.close();
        } catch (Exception e) {
        }
      }
    };
  }
  public void releaseService(BeanContextServices bcs, Object requestor,
      Object service) {
    // do nothing
  }
  public Iterator getCurrentServiceSelectors(BeanContextServices bcs,
      Class serviceClass) {
    return null; // do nothing
  }
}





Demonstration of set functionality in beans

/*
 *     file: BeanCollections.java
 *  package: oreilly.hcj.collections
 *
 * This software is granted under the terms of the Common Public License,
 * CPL, which may be found at the following URL:
 * http://www-124.ibm.ru/developerworks/oss/CPLv1.0.htm
 *
 * Copyright(c) 2003-2005 by the authors indicated in the @author tags.
 * All Rights are Reserved by the various authors.
 *
 ########## DO NOT EDIT ABOVE THIS LINE ########## */
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;
import java.beans.VetoableChangeSupport;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/*
 * file: Purchase.java package: oreilly.hcj.collections
 * 
 * This software is granted under the terms of the Common Public License, CPL,
 * which may be found at the following URL:
 * http://www-124.ibm.ru/developerworks/oss/CPLv1.0.htm
 * 
 * Copyright(c) 2003-2005 by the authors indicated in the @author tags. All
 * Rights are Reserved by the various authors.
 * 
 * ########## DO NOT EDIT ABOVE THIS LINE ##########
 */
/**
 * A demo purchase bean.
 * 
 * @author 
 * @version $Revision: 1.3 $
 */
public class BeanCollections {
  /** A demo customer set. */
  private static final Set CUSTOMERS;
  static {
    CUSTOMERS = new HashSet();
    try {
      Customer customer = null;
      HashSet purchs = null;
      // -- Joe
      customer = new Customer();
      customer.setName("Joe");
      purchs = new HashSet();
      purchs.add(new Purchase("Cat Food", 22.34f));
      purchs.add(new Purchase("Cat Treats", 5.45f));
      purchs.add(new Purchase("Cat Toy", 12.95f));
      customer.setPurchases(purchs);
      customer.setPurchases2(purchs);
      customer.setPurchases3(purchs);
      CUSTOMERS.add(customer);
      // -- Jon
      customer = new Customer();
      customer.setName("Jon");
      purchs = new HashSet();
      purchs.add(new Purchase("Dog Food", 35.95f));
      purchs.add(new Purchase("Dog Toy", 9.24f));
      customer.setPurchases(purchs);
      customer.setPurchases2(purchs);
      customer.setPurchases3(purchs);
      CUSTOMERS.add(customer);
      // -- Jane
      customer = new Customer();
      customer.setName("Jane");
      purchs = new HashSet();
      customer.setPurchases(purchs);
      customer.setPurchases2(purchs);
      customer.setPurchases3(purchs);
      CUSTOMERS.add(customer);
    } catch (final Exception ex) {
      ex.printStackTrace();
    }
  }
  /**
   * Main Method.
   * 
   * @param args
   *          command line arguments.
   */
  public static void main(String[] args) {
    try {
      Iterator iter = CUSTOMERS.iterator();
      Customer customer = null;
      while (iter.hasNext()) {
        customer = (Customer) iter.next();
        someFunction(customer);
        makeCustomerReport(customer);
      }
    } catch (final ClassCastException ex) {
      System.out.println("--- See? I told you. ---");
      ex.printStackTrace(System.out);
      System.out.flush();
    }
    System.out.println();
    System.out.println("--------------------------------------");
    System.out.println();
    // -- Write out the two types of report to show that they
    // do the same thing. Note that the order might be slightly
    // different due to the nature of Set iterators.
    makeGroupReport(CUSTOMERS);
    System.out.println();
    System.out.println("--------------------------------------");
    System.out.println();
    makeGroupReportBetter(CUSTOMERS);
  }
  /**
   * Make a purchases report for a customer.
   * 
   * @param customer
   *          The customer for which to make a report.
   * 
   * @throws NullPointerException
   *           If customers is null.
   */
  public static void makeCustomerReport(final Customer customer) {
    if (customer == null) {
      throw new NullPointerException();
    }
    Set purchases = customer.getPurchases();
    if (purchases != null) {
      Iterator iter = purchases.iterator();
      Purchase purch = null;
      System.out.println("Purchases for " + customer.getName());
      while (iter.hasNext()) {
        purch = (Purchase) iter.next();
        System.out.println(purch.getItemName() + "\t" + purch.getPrice());
      }
    }
  }
  /**
   * Prepare a report of purchases for the given customers. Example with
   * potential null in Set peoperties.
   * 
   * @param customers
   *          The customers for which to prepare a report.
   * 
   * @throws NullPointerException
   *           If customers is null.
   */
  public static void makeGroupReport(final Set customers) {
    if (customers == null) {
      throw new NullPointerException();
    }
    Iterator purchaseIter = null;
    Iterator customerIter = null;
    Set purchases = null;
    Customer customer = null;
    Purchase purch = null;
    customerIter = customers.iterator();
    while (customerIter.hasNext()) {
      customer = (Customer) customerIter.next();
      System.out.println("Purchases for " + customer.getName());
      purchases = customer.getPurchases3();
      if (purchases != null) {
        purchaseIter = purchases.iterator();
        while (purchaseIter.hasNext()) {
          purch = (Purchase) purchaseIter.next();
          System.out.println(purch.getItemName() + "\t" + purch.getPrice());
        }
      }
      System.out.print("Total Purchases = ");
      if (purchases != null) {
        System.out.println(purchases.size());
      } else {
        System.out.println(0);
      }
      System.out.println();
    }
  }
  /**
   * Prepare a report of purchases for the given customers. Example with
   * potential no nulls in Set peoperties.
   * 
   * @param customers
   *          The customers for which to prepare a report.
   * 
   * @throws NullPointerException
   *           If customers is null.
   */
  public static void makeGroupReportBetter(final Set customers) {
    if (customers == null) {
      throw new NullPointerException();
    }
    Iterator purchaseIter = null;
    Iterator customerIter = null;
    Set purchases = null;
    Customer customer = null;
    Purchase purch = null;
    customerIter = customers.iterator();
    while (customerIter.hasNext()) {
      customer = (Customer) customerIter.next();
      System.out.println("Purchases for " + customer.getName());
      purchases = customer.getPurchases3();
      purchaseIter = customer.getPurchases3().iterator();
      while (purchaseIter.hasNext()) {
        purch = (Purchase) purchaseIter.next();
        System.out.println(purch.getItemName() + "\t" + purch.getPrice());
      }
      System.out.println("Total Purchases = " + purchases.size());
      System.out.println();
    }
  }
  /**
   * Manipulate a customer.
   * 
   * @param customer
   *          The customer to manipulate.
   * 
   * @throws NullPointerException
   *           If customer is null.
   */
  public static void someFunction(final Customer customer) {
    if (customer == null) {
      throw new NullPointerException();
    }
    Set purchs = customer.getPurchases();
    Set names = new HashSet(); // going to use to store customer names.
    names.add(new String("Jason"));
    purchs.add(new String("Fred")); // typo, he meant names, not purchs.
  }
}
/* ########## End of File ########## */





How to create Java bean component

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;
import java.beans.VetoableChangeSupport;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
import javax.swing.event.SwingPropertyChangeSupport;
public class BakedBean extends JComponent implements Externalizable {
  // Property names
  public static final String BEAN_VALUE = "Value";
  public static final String BEAN_COLOR = "Color";
  // Properties
  private Font beanFont; // simple
  private Dimension beanDimension; // simple
  private int beanValue; // bound
  private Color beanColor; // constrained
  private String text; // change
  // Manages all PropertyChangeListeners
  protected SwingPropertyChangeSupport propertySupporter = new SwingPropertyChangeSupport(
      this);
  // Manages all VetoableChangeListeners
  protected VetoableChangeSupport vetoableChangeSupport = new VetoableChangeSupport(this);
  protected transient ChangeEvent changeEvent = null;
  protected EventListenerList listenerList = new EventListenerList();
  public BakedBean() {
    beanFont = new Font("SanSerif", Font.BOLD | Font.ITALIC, 12);
    beanDimension = new Dimension(150, 100);
    beanValue = 0;
    beanColor = Color.black;
    text = "BakedBean #";
  }
  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(beanColor);
    g.setFont(beanFont);
    g.drawString(text + beanValue, 30, 30);
  }
  public void setBeanFont(Font font) {
    beanFont = font;
  }
  public Font getBeanFont() {
    return beanFont;
  }
  public void setBeanValue(int newValue) {
    int oldValue = beanValue;
    beanValue = newValue;
    // Notify all PropertyChangeListeners
    propertySupporter.firePropertyChange(BEAN_VALUE, new Integer(oldValue),
        new Integer(newValue));
  }
  public int getBeanValue() {
    return beanValue;
  }
  public void setBeanColor(Color newColor) throws PropertyVetoException {
    Color oldColor = beanColor;
    vetoableChangeSupport.fireVetoableChange(BEAN_COLOR, oldColor, newColor);
    beanColor = newColor;
    propertySupporter.firePropertyChange(BEAN_COLOR, oldColor, newColor);
  }
  public Color getBeanColor() {
    return beanColor;
  }
  public void setBeanString(String newString) {
    text = newString;
    // Notify all ChangeListeners
    fireStateChanged();
  }
  public String getBeanString() {
    return text;
  }
  public void setPreferredSize(Dimension dim) {
    beanDimension = dim;
  }
  public Dimension getPreferredSize() {
    return beanDimension;
  }
  public void setMinimumSize(Dimension dim) {
    beanDimension = dim;
  }
  public Dimension getMinimumSize() {
    return beanDimension;
  }
  public void addPropertyChangeListener(PropertyChangeListener l) {
    propertySupporter.addPropertyChangeListener(l);
  }
  public void removePropertyChangeListener(PropertyChangeListener l) {
    propertySupporter.removePropertyChangeListener(l);
  }
  public void addVetoableChangeListener(VetoableChangeListener l) {
    vetoableChangeSupport.addVetoableChangeListener(l);
  }
  public void removeVetoableChangeListener(VetoableChangeListener l) {
    vetoableChangeSupport.removeVetoableChangeListener(l);
  }
  // Remember that EventListenerList is an array of
  // key/value pairs.
  // key = XXListener class reference
  // value = XXListener instance
  public void addChangeListener(ChangeListener l) {
    listenerList.add(ChangeListener.class, l);
  }
  public void removeChangeListener(ChangeListener l) {
    listenerList.remove(ChangeListener.class, l);
  }
  // EventListenerList dispatching code.
  protected void fireStateChanged() {
    Object[] listeners = listenerList.getListenerList();
    // Process the listeners last to first, notifying
    // those that are interested in this event
    for (int i = listeners.length - 2; i >= 0; i -= 2) {
      if (listeners[i] == ChangeListener.class) {
        if (changeEvent == null)
          changeEvent = new ChangeEvent(this);
        ((ChangeListener) listeners[i + 1]).stateChanged(changeEvent);
      }
    }
  }
  public void writeExternal(ObjectOutput out) throws IOException {
    out.writeObject(beanFont);
    out.writeObject(beanDimension);
    out.writeInt(beanValue);
    out.writeObject(beanColor);
    out.writeObject(text);
  }
  public void readExternal(ObjectInput in) throws IOException,
      ClassNotFoundException {
    setBeanFont((Font) in.readObject());
    setPreferredSize((Dimension) in.readObject());
    // Use preferred size for minimum size..
    setMinimumSize(getPreferredSize());
    setBeanValue(in.readInt());
    try {
      setBeanColor((Color) in.readObject());
    } catch (PropertyVetoException pve) {
      System.out.println("Color change vetoed..");
    }
    setBeanString((String) in.readObject());
  }
  public static void main(String[] args) {
    JFrame frame = new JFrame("BakedBean");
    frame.getContentPane().add(new BakedBean());
    frame.setVisible(true);
    frame.pack();
  }
}





how to use the instantiateChild() convenience method to create a bean automatically nested into a bean context

 
/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
import java.beans.beancontext.BeanContextChildSupport;
import java.beans.beancontext.BeanContextSupport;
import java.io.IOException;
/**
 * An example of how to use the instantiateChild() convenience method to create
 * a bean automatically nested into a bean context.
 */
public class Example3 {
  public static void main(String[] args) {
    BeanContextSupport context = new BeanContextSupport();
    System.out.println("Number of children nested into the context: "
        + context.size());
    BeanContextChildSupport child = null;
    try {
      child = (BeanContextChildSupport) context
          .instantiateChild("java.beans.beancontext.BeanContextChildSupport");
    } catch (IOException e) {
      System.out.println("IOException occurred: " + e.getMessage());
    } catch (ClassNotFoundException e) {
      System.out.println("Class not found: " + e.getMessage());
    }
    System.out.println("Number of children nested into the context: "
        + context.size());
  }
}





illustrate delivery of the BeanContextMembershipEvent

/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
import java.beans.beancontext.BeanContextChildSupport;
import java.beans.beancontext.BeanContextMembershipEvent;
import java.beans.beancontext.BeanContextMembershipListener;
import java.beans.beancontext.BeanContextSupport;
/**
 * A simple test program to illustrate delivery of the
 * BeanContextMembershipEvent.
 */
public class MembershipTest {
  public static void main(String[] args) {
    BeanContextSupport context = new BeanContextSupport(); // the context
    MyMembershipListener listener = new MyMembershipListener();
    BeanContextChildSupport bean = new BeanContextChildSupport(); // a JavaBean
    context.addBeanContextMembershipListener(listener); // now listening!
    context.add(bean);
    context.remove(bean);
  }
}
/**
 * A custom implementation of the BeanContextMembershipListener interface.
 */
class MyMembershipListener implements BeanContextMembershipListener {
  public void childrenAdded(BeanContextMembershipEvent bcme) {
    System.out.println("Another bean has been added to the context.");
  }
  public void childrenRemoved(BeanContextMembershipEvent bcme) {
    System.out.println("A bean has been removed from the context.");
  }
}





Simple Java bean container

import java.awt.Color;
import java.awt.ruponent;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;
import java.beans.VetoableChangeSupport;
import java.io.Externalizable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
import javax.swing.event.SwingPropertyChangeSupport;
public class BeanContainer extends JFrame implements FocusListener {
  protected File currentDir = new File(".");
  protected Component currentBean;
  protected String className = "MyBean";
  protected JFileChooser fileChooser = new JFileChooser();
  public BeanContainer() {
    super("Simple Bean Container");
    getContentPane().setLayout(new FlowLayout());
    setSize(300, 300);
    JPopupMenu.setDefaultLightWeightPopupEnabled(false);
    JMenuBar menuBar = createMenuBar();
    setJMenuBar(menuBar);
    WindowListener wndCloser = new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    };
    addWindowListener(wndCloser);
    setVisible(true);
  }
  protected JMenuBar createMenuBar() {
    JMenuBar menuBar = new JMenuBar();
    JMenu mFile = new JMenu("File");
    JMenuItem mItem = new JMenuItem("New...");
    ActionListener lst = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        NewBeanThread t = new NewBeanThread();  
        t.start();
      }
    };
    mItem.addActionListener(lst);
    mFile.add(mItem);
    mItem = new JMenuItem("Load...");
    lst = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        LoadBeanThread t = new LoadBeanThread();
        t.start();
      }
    };
    mItem.addActionListener(lst);
    mFile.add(mItem);
    mItem = new JMenuItem("Save...");
    lst = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        SaveBeanThread t = new SaveBeanThread();  
        t.start();
      }
    };
    mItem.addActionListener(lst);
    mFile.add(mItem);
    mFile.addSeparator();
    mItem = new JMenuItem("Exit");
    lst = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        System.exit(0);
      }
    };
    mItem.addActionListener(lst);
    mFile.add(mItem);
    menuBar.add(mFile);
    JMenu mEdit = new JMenu("Edit");
    mItem = new JMenuItem("Delete");
    lst = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        if (currentBean == null)
          return;
        getContentPane().remove(currentBean);
        currentBean = null;
        validate();
        repaint();
      }
    };
    mItem.addActionListener(lst);
    mEdit.add(mItem);
    menuBar.add(mEdit);
    JMenu mLayout = new JMenu("Layout");
    ButtonGroup group = new ButtonGroup();
    mItem = new JRadioButtonMenuItem("FlowLayout");
    mItem.setSelected(true);
    lst = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        getContentPane().setLayout(new FlowLayout());
        validate();
        repaint();
      }
    };
    mItem.addActionListener(lst);
    group.add(mItem);
    mLayout.add(mItem);
    mItem = new JRadioButtonMenuItem("GridLayout");
    lst = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        int col = 3;
        int row = (int) Math.ceil(getContentPane().getComponentCount()
            / (double) col);
        getContentPane().setLayout(new GridLayout(row, col, 10, 10));
        validate();
        repaint();
      }
    };
    mItem.addActionListener(lst);
    group.add(mItem);
    mLayout.add(mItem);
    mItem = new JRadioButtonMenuItem("BoxLayout - X");
    lst = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        getContentPane().setLayout(
            new BoxLayout(getContentPane(), BoxLayout.X_AXIS));
        validate();
        repaint();
      }
    };
    mItem.addActionListener(lst);
    group.add(mItem);
    mLayout.add(mItem);
    mItem = new JRadioButtonMenuItem("BoxLayout - Y");
    lst = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        getContentPane().setLayout(
            new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
        validate();
        repaint();
      }
    };
    mItem.addActionListener(lst);
    group.add(mItem);
    mLayout.add(mItem);
    group.add(mItem);
    mLayout.add(mItem);
    menuBar.add(mLayout);
    return menuBar;
  }
  public void focusGained(FocusEvent e) {
    currentBean = e.getComponent();
    repaint();
  }
  public void focusLost(FocusEvent e) {
  }
  // This is a heavyweight component so we override paint
  // instead of paintComponent. super.paint(g) will
  // paint all child components first, and then we
  // simply draw over top of them.
  public void paint(Graphics g) {
    super.paint(g);
    if (currentBean == null)
      return;
    Point pt = getLocationOnScreen();
    Point pt1 = currentBean.getLocationOnScreen();
    int x = pt1.x - pt.x - 2;
    int y = pt1.y - pt.y - 2;
    int w = currentBean.getWidth() + 2;
    int h = currentBean.getHeight() + 2;
    g.setColor(Color.black);
    g.drawRect(x, y, w, h);
  }
  public static void main(String argv[]) {
    new BeanContainer();
  }
  class SaveBeanThread extends Thread {
    public void run() {
      if (currentBean == null)
        return;
      fileChooser
          .setDialogTitle("Please choose file to serialize bean");
      fileChooser.setCurrentDirectory(currentDir);
      int result = fileChooser
          .showSaveDialog(BeanContainer.this);
      repaint();
      if (result != JFileChooser.APPROVE_OPTION)
        return;
      currentDir = fileChooser.getCurrentDirectory();
      File fChoosen = fileChooser.getSelectedFile();
      try {
        FileOutputStream fStream = new FileOutputStream(
            fChoosen);
        ObjectOutput stream = new ObjectOutputStream(
            fStream);
        stream.writeObject(currentBean);
        stream.close();
        fStream.close();
      } catch (Exception ex) {
        ex.printStackTrace();
        JOptionPane.showMessageDialog(BeanContainer.this,
            "Error: " + ex.toString(), "Warning",
            JOptionPane.WARNING_MESSAGE);
      }
    }
  }
  class LoadBeanThread extends Thread{
    public void run() {
      fileChooser.setCurrentDirectory(currentDir);
      fileChooser
          .setDialogTitle("Please select file with serialized bean");
      int result = fileChooser
          .showOpenDialog(BeanContainer.this);
      repaint();
      if (result != JFileChooser.APPROVE_OPTION)
        return;
      currentDir = fileChooser.getCurrentDirectory();
      File fChoosen = fileChooser.getSelectedFile();
      try {
        FileInputStream fStream = new FileInputStream(
            fChoosen);
        ObjectInput stream = new ObjectInputStream(fStream);
        Object obj = stream.readObject();
        if (obj instanceof Component) {
          currentBean = (Component) obj;
          currentBean
              .addFocusListener(BeanContainer.this);
          currentBean.requestFocus();
          getContentPane().add(currentBean);
        }
        stream.close();
        fStream.close();
        validate();
      } catch (Exception ex) {
        ex.printStackTrace();
        JOptionPane.showMessageDialog(BeanContainer.this,
            "Error: " + ex.toString(), "Warning",
            JOptionPane.WARNING_MESSAGE);
      }
      repaint();
    }
  }
  class NewBeanThread extends Thread {
    public void run() {
      String result = (String) JOptionPane.showInputDialog(
          BeanContainer.this,
          "Use the following name for demanstration",
          "Input", JOptionPane.INFORMATION_MESSAGE, null,
          null, className);
      repaint();
      if (result == null)
        return;
      try {
        className = result;
        Class cls = Class.forName(result);
        Object obj = cls.newInstance();
        if (obj instanceof Component) {
          currentBean = (Component) obj;
          currentBean
              .addFocusListener(BeanContainer.this);
          currentBean.requestFocus();
          getContentPane().add(currentBean);
        }
        validate();
      } catch (Exception ex) {
        ex.printStackTrace();
        JOptionPane.showMessageDialog(BeanContainer.this,
            "Error: " + ex.toString(), "Warning",
            JOptionPane.WARNING_MESSAGE);
      }
    }
  }
}
class MyBean extends JComponent implements Externalizable {
  // Property names
  public static final String BEAN_VALUE = "Value";
  public static final String BEAN_COLOR = "Color";
  // Properties
  private Font beanFont; // simple
  private Dimension beanDimension; // simple
  private int beanValue; // bound
  private Color beanColor; // constrained
  private String text; // change
  // Manages all PropertyChangeListeners
  protected SwingPropertyChangeSupport propertySupporter = new SwingPropertyChangeSupport(
      this);
  // Manages all VetoableChangeListeners
  protected VetoableChangeSupport vetoableChangeSupport = new VetoableChangeSupport(this);
  protected transient ChangeEvent changeEvent = null;
  protected EventListenerList listenerList = new EventListenerList();
  public MyBean() {
    beanFont = new Font("SanSerif", Font.BOLD | Font.ITALIC, 12);
    beanDimension = new Dimension(150, 100);
    beanValue = 0;
    beanColor = Color.black;
    text = "BakedBean #";
  }
  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(beanColor);
    g.setFont(beanFont);
    g.drawString(text + beanValue, 30, 30);
  }
  public void setBeanFont(Font font) {
    beanFont = font;
  }
  public Font getBeanFont() {
    return beanFont;
  }
  public void setBeanValue(int newValue) {
    int oldValue = beanValue;
    beanValue = newValue;
    // Notify all PropertyChangeListeners
    propertySupporter.firePropertyChange(BEAN_VALUE, new Integer(oldValue),
        new Integer(newValue));
  }
  public int getBeanValue() {
    return beanValue;
  }
  public void setBeanColor(Color newColor) throws PropertyVetoException {
    Color oldColor = beanColor;
    vetoableChangeSupport.fireVetoableChange(BEAN_COLOR, oldColor, newColor);
    beanColor = newColor;
    propertySupporter.firePropertyChange(BEAN_COLOR, oldColor, newColor);
  }
  public Color getBeanColor() {
    return beanColor;
  }
  public void setBeanString(String newString) {
    text = newString;
    // Notify all ChangeListeners
    fireStateChanged();
  }
  public String getBeanString() {
    return text;
  }
  public void setPreferredSize(Dimension dim) {
    beanDimension = dim;
  }
  public Dimension getPreferredSize() {
    return beanDimension;
  }
  public void setMinimumSize(Dimension dim) {
    beanDimension = dim;
  }
  public Dimension getMinimumSize() {
    return beanDimension;
  }
  public void addPropertyChangeListener(PropertyChangeListener l) {
    propertySupporter.addPropertyChangeListener(l);
  }
  public void removePropertyChangeListener(PropertyChangeListener l) {
    propertySupporter.removePropertyChangeListener(l);
  }
  public void addVetoableChangeListener(VetoableChangeListener l) {
    vetoableChangeSupport.addVetoableChangeListener(l);
  }
  public void removeVetoableChangeListener(VetoableChangeListener l) {
    vetoableChangeSupport.removeVetoableChangeListener(l);
  }
  // Remember that EventListenerList is an array of
  // key/value pairs.
  // key = XXListener class reference
  // value = XXListener instance
  public void addChangeListener(ChangeListener l) {
    listenerList.add(ChangeListener.class, l);
  }
  public void removeChangeListener(ChangeListener l) {
    listenerList.remove(ChangeListener.class, l);
  }
  // EventListenerList dispatching code.
  protected void fireStateChanged() {
    Object[] listeners = listenerList.getListenerList();
    // Process the listeners last to first, notifying
    // those that are interested in this event
    for (int i = listeners.length - 2; i >= 0; i -= 2) {
      if (listeners[i] == ChangeListener.class) {
        if (changeEvent == null)
          changeEvent = new ChangeEvent(this);
        ((ChangeListener) listeners[i + 1]).stateChanged(changeEvent);
      }
    }
  }
  public void writeExternal(ObjectOutput out) throws IOException {
    out.writeObject(beanFont);
    out.writeObject(beanDimension);
    out.writeInt(beanValue);
    out.writeObject(beanColor);
    out.writeObject(text);
  }
  public void readExternal(ObjectInput in) throws IOException,
      ClassNotFoundException {
    setBeanFont((Font) in.readObject());
    setPreferredSize((Dimension) in.readObject());
    // Use preferred size for minimum size..
    setMinimumSize(getPreferredSize());
    setBeanValue(in.readInt());
    try {
      setBeanColor((Color) in.readObject());
    } catch (PropertyVetoException pve) {
      System.out.println("Color change vetoed..");
    }
    setBeanString((String) in.readObject());
  }
  public static void main(String[] args) {
    JFrame frame = new JFrame("BakedBean");
    frame.getContentPane().add(new MyBean());
    frame.setVisible(true);
    frame.pack();
  }
}





Use assert the verify value

/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
public class Card {
  private final int rank;
  private final int suit;
  // Kinds of suits
  public final static int DIAMONDS = 1;
  public final static int CLUBS = 2;
  public final static int HEARTS = 3;
  public final static int SPADES = 4;
  // Kinds of ranks
  public final static int ACE = 1;
  public final static int DEUCE = 2;
  public final static int THREE = 3;
  public final static int FOUR = 4;
  public final static int FIVE = 5;
  public final static int SIX = 6;
  public final static int SEVEN = 7;
  public final static int EIGHT = 8;
  public final static int NINE = 9;
  public final static int TEN = 10;
  public final static int JACK = 11;
  public final static int QUEEN = 12;
  public final static int KING = 13;
  public Card(int rank, int suit) {
    assert isValidRank(rank);
    assert isValidSuit(suit);
    this.rank = rank;
    this.suit = suit;
  }
  public int getSuit() {
    return suit;
  }
  public int getRank() {
    return rank;
  }
  public static boolean isValidRank(int rank) {
    return ACE <= rank && rank <= KING;
  }
  public static boolean isValidSuit(int suit) {
    return DIAMONDS <= suit && suit <= SPADES;
  }
  public static String rankToString(int rank) {
    switch (rank) {
    case ACE:
      return "Ace";
    case DEUCE:
      return "Deuce";
    case THREE:
      return "Three";
    case FOUR:
      return "Four";
    case FIVE:
      return "Five";
    case SIX:
      return "Six";
    case SEVEN:
      return "Seven";
    case EIGHT:
      return "Eight";
    case NINE:
      return "Nine";
    case TEN:
      return "Ten";
    case JACK:
      return "Jack";
    case QUEEN:
      return "Queen";
    case KING:
      return "King";
    default:
      // Handle an illegal argument. There are generally two
      // ways to handle invalid arguments, throwing an exception
      // (see the section on Handling Exceptions) or return null
      return null;
    }
  }
  public static String suitToString(int suit) {
    switch (suit) {
    case DIAMONDS:
      return "Diamonds";
    case CLUBS:
      return "Clubs";
    case HEARTS:
      return "Hearts";
    case SPADES:
      return "Spades";
    default:
      return null;
    }
  }
  public static void main(String[] args) {
    // must run program with -ea flag (java -ea ..) to
    // use assert statements
    assert rankToString(ACE) == "Ace";
    assert rankToString(DEUCE) == "Deuce";
    assert rankToString(THREE) == "Three";
    assert rankToString(FOUR) == "Four";
    assert rankToString(FIVE) == "Five";
    assert rankToString(SIX) == "Six";
    assert rankToString(SEVEN) == "Seven";
    assert rankToString(EIGHT) == "Eight";
    assert rankToString(NINE) == "Nine";
    assert rankToString(TEN) == "Ten";
    assert rankToString(JACK) == "Jack";
    assert rankToString(QUEEN) == "Queen";
    assert rankToString(KING) == "King";
    assert suitToString(DIAMONDS) == "Diamonds";
    assert suitToString(CLUBS) == "Clubs";
    assert suitToString(HEARTS) == "Hearts";
    assert suitToString(SPADES) == "Spades";
  }
}