Core java 2 第二卷上的实例,我这里只处理一个 titlePosition 属性。首先,新建一个 bean。package testApp;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.beans.IndexedPropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JComponent;
/**
 * A bean to draw a bar chart.
 * @version 1.31 2007-10-03
 * @author Cay Horstmann
 */
public class ChartBean extends JComponent
{
   public ChartBean()
   {
      setPreferredSize(new Dimension(XPREFSIZE, YPREFSIZE));
   }
    @Override
   public void paintComponent(Graphics g)
   {
      Graphics2D g2 = (Graphics2D) g;      if (values == null || values.length == 0) return;
      double minValue = 0;
      double maxValue = 0;
      for (int i = 0; i < values.length; i++)
      {
         if (minValue > getValues(i)) minValue = getValues(i);
         if (maxValue < getValues(i)) maxValue = getValues(i);
      }
      if (maxValue == minValue) return;      Rectangle2D bounds = getBounds();
      double clientWidth = bounds.getWidth();
      double clientHeight = bounds.getHeight();
      double barWidth = (clientWidth - 2 * INSETS) / values.length;      g2.setPaint(inverse ? color : Color.white);
      g2.fill(new Rectangle2D.Double(0, 0, clientWidth, clientHeight));
      g2.setPaint(Color.black);      Font titleFont = new Font("SansSerif", Font.BOLD, 20);
      FontRenderContext context = g2.getFontRenderContext();
      Rectangle2D titleBounds = titleFont.getStringBounds(title, context);      double titleWidth = titleBounds.getWidth();
      double y = -titleBounds.getY();
      double x = 0;
      if (titlePosition == Position.CENTER) x += (clientWidth - titleWidth) / 2;
      else if (titlePosition == Position.RIGHT) x += clientWidth - titleWidth;      g2.setFont(titleFont);
      g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
            RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
      g2.drawString(title, (float) x, (float) y);
      double top = titleBounds.getHeight();
      double scale = (clientHeight - top - 2 * INSETS) / (maxValue - minValue);
      y = clientHeight;
      for (int i = 0; i < values.length; i++)
      {
         double x1 = INSETS + i * barWidth + 1;
         double y1 = INSETS + top;
         double value = getValues(i);
         double height = value * scale;
         if (value >= 0) y1 += (maxValue - value) * scale;
         else
         {
            y1 += (int) (maxValue * scale);
            height = -height;
         }
         g2.setPaint(inverse ? Color.white : color);
         Rectangle2D bar = new Rectangle2D.Double(x1, y1, barWidth - 2, height);
         g2.fill(bar);
         g2.setPaint(Color.black);
         g2.draw(bar);
      }
   }   /**
    * Sets the title property.
    * @param t the new chart title.
    */
   public void setTitle(String t)
   {
      title = t;
   }   /**
    * Gets the title property.
    * @return the chart title.
    */
   public String getTitle()
   {
      return title;
   }   /**
    * Sets the indexed values property.
    * @param newValue the values to display in the chart.
    */
   public void setValues(double[] newValue)
   {
      double[] oldValue = values;
      firePropertyChange("values", oldValue, newValue);
      values = newValue;
   }   /**
    * Gets the indexed values property.
    * @return the values to display in the chart.
    */
   public double[] getValues()
   {
      return values;
   }   /**
    * Sets the indexed values property.
    * @param i the index of the value to set
    * @param value the new value for that index
    */
   public void setValues(int i, double value)
   {
      if (0 <= i && i < values.length)
      {
         double oldValue = values[i];
         values[i] = value;
         for (PropertyChangeListener listener : getPropertyChangeListeners())
            listener.propertyChange(new IndexedPropertyChangeEvent(this, "values", oldValue,
                  value, i));
      }
   }   /**
    * Gets the indexed values property.
    * @param i the index of the value to get
    * @return the value for that index
    */
   public double getValues(int i)
   {
      if (0 <= i && i < values.length) return values[i];
      return 0;
   }   /**
    * Sets the inverse property.
    * @param b true if the display is inverted (white bars on colored background)
    */
   public void setInverse(boolean b)
   {
      inverse = b;
   }   /**
    * Gets the inverse property.
    * @return true if the display is inverted
    */
   public boolean isInverse()
   {
      return inverse;
   }   /**
    * Sets the titlePosition property.
    * @param p LEFT, CENTER, or RIGHT
    */
   public void setTitlePosition(Position p)
   {
      titlePosition = p;
   }   /**
    * Gets the titlePosition property.
    * @return LEFT, CENTER, or RIGHT
    */
   public Position getTitlePosition()
   {
      return titlePosition;
   }   /**
    * Sets the graphColor property.
    * @param c the color to use for the graph
    */
   public void setGraphColor(Color c)
   {
      color = c;
   }   /**
    * Gets the graphColor property.
    * @param c the color to use for the graph
    */
   public Color getGraphColor()
   {
      return color;
   }
   
   public enum Position { LEFT, CENTER, RIGHT };   private static final int XPREFSIZE = 300;
   private static final int YPREFSIZE = 300;   private static final int INSETS = 10;   private double[] values = { 1,2,3};
   private String title = "Title";
   private Position titlePosition = Position.CENTER;
   private boolean inverse;
   private Color color = Color.red;
}然后,在同一个包下新建一个 beanInfo 文件。
package testApp;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.beans.SimpleBeanInfo;
public class ChartBeanBeanInfo extends SimpleBeanInfo
{
    public ChartBeanBeanInfo()
    {
        try
        {
            PropertyDescriptor titlePositionDescriptor =
                    new PropertyDescriptor("titlePosition", ChartBean.class);
            titlePositionDescriptor.setPropertyEditorClass(TitlePositonEditor.class);
             propertyDescriptors = new PropertyDescriptor[]
            {
                titlePositionDescriptor
            };
        }
        catch (IntrospectionException e)
        {
        }
    }
    @Override
    public PropertyDescriptor[] getPropertyDescriptors()
    {
        return propertyDescriptors;
    }
    private PropertyDescriptor[] propertyDescriptors;
}再创建一个属性编辑器文件。
package testApp;
import java.beans.PropertyEditorSupport;
import java.util.Arrays;
class TitlePositonEditor extends PropertyEditorSupport
{
    @Override
public String[] getTags()
{
return tags;
}
    @Override
public String getAsText()
{
int index=((ChartBean.Position)getValue()).ordinal();
return tags[index];
}
    @Override
public void setAsText(String s)
{
int index=Arrays.asList(tags).indexOf(s);
if(index>=0)
setValue(ChartBean.Position.values()[index]);
}    @Override
    public String getJavaInitializationString()
    {
        return ChartBean.Position.class.getName().replace('$', '.')+getValue();
    }
    private String[] tags={"Left","Center","Right"};
}
然后,无论我用 cmd 的 jar 命令创建 ChartBean.jar 还是用 NetBeans 的添加到面板功能,生成的 Bean 都和预期的不同。在属性里面,titlePosition 应该显示 属性编辑器 TitlePositonEditor 里面的字符串数组里面的值 Left,Center,Right,这里显示的情况是 LEFT,CENTER,RIGHT,NULL四个选项,和只有一个ChartBean文件的效果一样。
   我知道我没有把这3个文件关联起来,请指教一下,创建这三个文件后,怎么操作才可以把他们关联起来。
最好有详细步骤,看到预期效果。我是新手。谢谢。