HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML
 

"On JavaBeans Customization"
Volume: 4 Issue: 5, p. 14

	

Listing 1. The CustomizerImpl class.
 
abstract public class CustomizerImpl extends 
         JPanel implements Customizer{ 
  public Object bean; 
  public PropertyChangeSupport pcs; 
  public String title = "Customizer"; 
  //This method is called by the builder tool to 
  //pass object instance to the target bean. 
  public void setObject(Object bnObj){ 
   bean = bnObj; 
   pcs = new PropertyChangeSupport(bean); 
   createGUI(); 
  } 
  
  //Title read/write methods 
  public void setTitle(String title){this.title = title;} 
  public String getTitle(){return title;} 

  //This method is overriden so as to set the customizer title. 
  public void addNotify(){ 
   super.addNotify(); 
   Component cmp = getParent(); 
   if(cmp instanceof Dialog) ((Dialog)cmp).setTitle(title); 
   if(cmp instanceof JFrame) ((JFrame)cmp).setTitle(title); 
   if(cmp instanceof JDialog)((JDialog)cmp).setTitle(title); 
  } 

  //Adds property change event listeners 
  public void addPropertyChangeListener(PropertyChangeListener p){ 
   //Delegate the event firing job to pcs. 
   pcs.addPropertyChangeListener(p); 
  } 

  //Removes property change listeners 
  public void removePropertyChangeListener(PropertyChangeListener p){ 
   pcs.removePropertyChangeListener(p); 
  } 

  //All the subclasses have to implement this method. 
  abstract protected void createGUI(); 
} 

Listing 2. Creating a JTextField component.
 
/* Creates an edit field for any primitive type of property. 
 * Uses the relection API to invoke the getter method. Since the 
 * JTextField’s input and output is only text, the property 
 * type is needed to convert its input and output. 
 * @param obj the bean object. 
 * @param pc the property change support object. 
 * @param name the property name. 
 * @param clType the property class type. 
 */ 
public static JTextField createJTextField(Object obj, 
                     PropertyChangeSupport pc, 
                     String name, 
                     Class clType){ 
  final Object bean = obj; 
  final PropertyChangeSupport pcs = pc; 
  final String propName = name; 
  final Class type = clType; 
  JTextField jtf = new JTextField(5); 
  String str = "get"+propName; 
  //Get the current property value as an object 
  Object probject= getProperty(bean, propName); 
  //Display it 
  jtf.setText(probject.toString()); 
  jtf.addActionListener( 
   new ActionListener() { 
    public void actionPerformed(ActionEvent e){ 
      try{ 
       //Get the modified property as a text string 
       String txt =((JTextField)(e.getSource())).getText(); 
       //Convert the text string to actual property value. 
       Object propValue = convertStringToObject(type,txt); 
       //delegates firing of property change event to pcs 
       pcs.firePropertyChange(propName, null, propValue); 
      }catch(Exception x){ x.printStackTrace(); } 
    } 
   } 
  ); 
  return jtf; 
} 

Listing 3. Getting the property value.
 
/** This method fetches the current value of a property. 
 * @param bean the target bean. 
 * @param propName the prperty name. 
 */ 
public static Object getProperty(Object bean, 
                 String propName){ 
  try{ 
    Class bcl = bean.getClass(); 
    //Construct the "getter" method name. 
    String str = "get"+propName; 
    //First create the Method object for the "getter" method 
    //No arguments for getter method 
    Method getM = bcl.getMethod(str, null); 
    //Use the Method object to invoke the "getter"method 
    Object args[] = { }; 
    return getM.invoke(bean, args); 
  } catch(Exception e){e.printStackTrace();} 
} 

Listing 4. Creating an increment/decrement button panel.
 
/** Creates a panel with "+" and "-" buttons. 
 * @param prName the property name. 
 * @param JLabelStr the JLabel string. 
 */ 
public static JPanel createIncrPanel(Object target, 
                   PropertyChangeSupport pc, 
                   String prName, 
                   String JLabelStr){ 
  JButton incr = new JButton("+"); 
  IncrButtonAdapter incrada = new IncrButtonAdapter(target, 
                           pc, 
                           prName, 2); 
  incr.addActionListener(incrada); 

  JButton decr = new JButton("-"); 
  IncrButtonAdapter decrada = new IncrButtonAdapter(target, 
                           pc, 
                           prName, -2); 
  decr.addActionListener(decrada); 

  JLabel inclab = new JLabel(JLabelStr); 
  JPanel pan = new JPanel(); 
  pan.add(inclab); 
  pan.add(incr); 
  pan.add(decr); 
  return pan; 
} 

Listing 5. The adapter class for "+" and "-" buttons.
 
//This is an inner class in CustomizerUtil.java. 
static class IncrButtonAdapter implements ActionListener{ 
  int increment; 
  String propName; 
  Object bean; 
  PropertyChangeSupport psc; 
  public IncrButtonAdapter(Object target, 
              PropertyChangeSupport pc, 
              String pr, 
              int incr) { 
   bean = target; 
   psc = pc; 
   increment = incr; 
   propName = pr; 
  } 
  
  public void actionPerformed(ActionEvent e){ 
   try{ 
    Integer num = (Integer)getProperty(bean,propName); 
    Object invarg[] = {new Integer(num.intValue()+ increment)}; 
    psc.firePropertyChange(propName, null, invarg[0]); 
   } catch(Exception x){System.out.println(x);} 
  } 
} 

Listing 6. The PieChartCustomizer class
 
public class PieChartCustomizer extends CustomizerImpl{ 
  public PieChart target; 
  public PieChartCustomizer(){setTitle("Pie Chart Customizer");} 
  protected void createGUI(){ 
   target = (PieChart)bean; 
   JPanel pan = new JPanel(); 
   JPanel colorspan = createColorsPanel(); 
   JPanel JLabelspan = createLabelsPanel(); 
   JPanel incrpan = new JPanel(); 
   JPanel diapan = CustomizerUtil.createIncrPanel( 
                         target, 
                         pcs, 
                         "PieDiaIncr", 
                         "Diameter"); 
   JPanel centpan = CustomizerUtil.createXYIncrPanel( 
                         target, 
                         pcs, 
                         "PieCenterXIncr", 
                         "PieCenterYIncr", 
                         "Center"); 
   incrpan.add(diapan); 
   incrpan.add(centpan); 
   incrpan.setBorder(BorderFactory.createTitledBorder("Pie")); 

   JPanel legpan = new JPanel(); 
   JPanel legpospan = CustomizerUtil.createXYIncrPanel( 
                         target, 
                         pcs, 
                         "LegendPosXIncr", 
                         "LegendPosYIncr", 
                         "Position"); 
   JPanel leggappan = CustomizerUtil.createIncrPanel( 
                         target, 
                         pcs, 
                         "LegendGapIncr", 
                         "Gap"); 
   legpan.add(leggappan); 
   legpan.add(legpospan); 
   legpan.setBorder(BorderFactory.createTitledBorder("Legend")); 
   // Gridbag Layout code 
   // ... 
  } 

  // Creates a panel for the colors. 
  public JPanel createColorsPanel(){ 
   JLabel bklab = new JLabel("Background"); 
   JComboBox bk = CustomizerUtil.createColorComboBox(target, 
                            pcs, 
                            "Background"); 
   JLabel fglab = new JLabel("Foreground"); 
   JComboBox fg = CustomizerUtil.createColorComboBox(target, 
                            pcs, 
                            "Foreground"); 
   Component comp[] = {bklab,bk,fglab,fg}; 
   JPanel pan = CustomizerUtil.doGridbagLayout(comp, 2); 
   pan.setBorder(BorderFactory.createTitledBorder("Colors")); 
   return pan; 
  } 
  //Creates a panel for the lables. 
  public JPanel createLabelsPanel(){ 
   JLabel tlab = new JLabel("Title"); 
   JTextField tl = CustomizerUtil.createJTextField(target,pcs, 
                           "TitleString", 
                           String.class); 
   Component comp[] = {tlab,tl}; 
   JPanel pan = CustomizerUtil.doGridbagLayout(comp,2); 
   pan.setBorder(BorderFactory.createTitledBorder("Labels")); 
   return pan; 
  } 
} 

Listing 7. The pop-up menu event handling code.
 
JMenuItem custitem = new JMenuItem("Customize"); 
custitem.addActionListener( 
  new ActionListener(){ 
   public void actionPerformed(ActionEvent e){ 
    try{ 
      Class cust = getCustomizerClass(); 
      launchCustomizer(cust); 
    } catch(Exception e1) {} 
   } 
  } 
); 

Listing 8. Launching a custimizer at runtime.
 
protected void launchCustomizer(Class cl) 
   throws InstantiationException, IllegalAccessException { 
  final Object bean = this; 
  Component cmp = (Component)cl.newInstance(); 
  if(!(cmp instanceof java.beans.Customizer)) return; 
  Customizer customizer = ((java.beans.Customizer)cmp); 
  customizer.setObject(bean); 
  customizer.addPropertyChangeListener( 
   new PropertyChangeListener() { 
     public void propertyChange(PropertyChangeEvent e) { 
      Object newVal = e.getNewValue(); 
      String propName = e.getPropertyName(); 
      CustomizerUtil.setProperty(bean, propName, newVal); 
     } 
   } 
  ); 
  //rest of the code 
  // ... 
} 

Listing 9. Setting the value of a property.
 
/** This method sets the value of a property. 
 * @param bean the target object 
 * @param propName the property name 
 * @param propValue the value of the property as text. 
 */ 
public static void setProperty(Object bean, 
              String propName, 
              Object propValue){ 
  try{ 
    Class bcl = bean.getClass(); 
    //Construct the "setter" method. 
    String str = "set"+propName; 
    //Create the parameter Class objects 
    Class cls = propValue.getClass(); 
    Class type = getType(propValue); 
    Class[] paraobj = {type}; 
    //Create the "setter" method object. 
    Method setM = bcl.getMethod(str, paraobj); 
    //Construct the argument objects 
    Object args[] = {propValue}; 
    //Invoke the "setter" method in the bean 
    setM.invoke(bean, args); 
  } catch(Exception e){e.printStackTrace();} 
} 




  

 

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: [email protected]

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.