BindingFactory.java
上传用户:zhengdagz
上传日期:2014-03-06
资源大小:1956k
文件大小:12k
源码类别:

xml/soap/webservice

开发平台:

Java

  1. /*
  2.  * $Id: BindingFactory.java,v 1.2 2005/10/10 17:00:51 rbair Exp $
  3.  *
  4.  * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
  5.  * Santa Clara, California 95054, U.S.A. All rights reserved.
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  * 
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  * 
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  20.  */
  21. package org.jdesktop.binding.swingx;
  22. import java.util.HashMap;
  23. import java.util.Iterator;
  24. import java.util.Map;
  25. import java.util.Set;
  26. import javax.swing.JButton;
  27. import javax.swing.JCheckBox;
  28. import javax.swing.JComboBox;
  29. import javax.swing.JComponent;
  30. import javax.swing.JLabel;
  31. import javax.swing.JList;
  32. import javax.swing.JSpinner;
  33. import javax.swing.JTable;
  34. import javax.swing.JTextArea;
  35. import javax.swing.SwingConstants;
  36. import javax.swing.text.JTextComponent;
  37. import org.jdesktop.binding.DataModel;
  38. import org.jdesktop.swingx.JXDatePicker;
  39. import org.jdesktop.swingx.JXHyperlink;
  40. import org.jdesktop.swingx.JXImagePanel;
  41. import org.jdesktop.swingx.JXRadioGroup;
  42. /**
  43.  * Choosing strategy for creating Bindings.<p>
  44.  *
  45.  * Extracted from DefaultFormFactory to have a 
  46.  * "pluggable" place for creating custom bindings. The usage
  47.  * of a BindingCreator should be viewed as an implementation
  48.  * detail, they don't do much.
  49.  *
  50.  * PENDING: there's a implicit coupling to ComponentMap -
  51.  * the BindingMap assumes that the ComponentMap did a
  52.  * good enough job when choosing components. <p>
  53.  *
  54.  * PENDING: should be factored into an interface and
  55.  * a default implementation.<p>
  56.  *
  57.  * PENDING: really want to configure the component here?
  58.  *
  59.  * @author Jeanette Winzenburg
  60.  */
  61. public class BindingFactory {
  62.   private Map bindingMap;
  63.   private static BindingFactory instance;
  64. private LabelMetaBindingCreator metaBindingCreator;
  65.   
  66.   
  67.   public static BindingFactory getInstance() {
  68.     // this is not thread safe...  
  69.     if (instance == null) {
  70.       instance = new BindingFactory();
  71.     }
  72.     return instance;
  73.   }
  74.   public static void setInstance(BindingFactory bindingMap) {
  75.     instance = bindingMap;
  76.   }
  77.   /**
  78.    * Creates and returns Binding between the
  79.    * component and a field of the DataModel.
  80.    *  
  81.    *  PENDING: null return value? Or better 
  82.    *  throw BindingException if no appropriate creator found?
  83.    *  
  84.    * @param component
  85.    * @param model
  86.    * @param fieldName
  87.    * @return 
  88.    * 
  89.    * @throws NullPointerException if any of the parameters is null.
  90.    */
  91.   public Binding createBinding(JComponent component, DataModel model, String fieldName) {
  92.     BindingCreator creator = getBindingCreator(component);
  93.     if (creator != null) {
  94.         return creator.createBinding(component, model, fieldName);
  95.     }
  96.     return null;
  97.   }
  98.   /**
  99.    * Creates and returns Binding between the
  100.    * component and the metaData of a field of the DataModel.
  101.    * Typically this is used to bind a label to the label
  102.    * property of the field's metaData.
  103.    *  
  104.    *  PENDING: null return value? Or better 
  105.    *  throw BindingException if no appropriate creator found?
  106.    *  
  107.    * @param component
  108.    * @param model
  109.    * @param fieldName
  110.    * @return 
  111.    * 
  112.    * @throws NullPointerException if any of the parameters is null.
  113.    */
  114.   public Binding createMetaBinding(JLabel label, DataModel model, String fieldName) {
  115.       BindingCreator creator = getMetaBindingCreator();
  116.       if (creator != null) {
  117.           return creator.createBinding(label, model, fieldName);
  118.       }
  119.       return null;
  120.   }
  121.   /**
  122.    * creates and returns a Binding between the label and 
  123.    * the MetaData of the given binding's field.
  124.    *  
  125.    */
  126. //  public Binding createMetaBinding(JLabel label, Binding binding) {
  127. //      BindingCreator creator = getMetaBindingCreator();
  128. //      if (creator != null) {
  129. //          return creator.createBinding(label, binding.getDataModel(), binding.getFieldName());
  130. //      }
  131. //      return null;
  132. //  }
  133.   /**
  134.    * returns the unique BindingCreator for binding (a label) to
  135.    * the metaData - typically to the label property.
  136.    * 
  137.    * @return
  138.    */
  139.   protected BindingCreator getMetaBindingCreator() {
  140.       if (metaBindingCreator == null) {
  141.           metaBindingCreator = new LabelMetaBindingCreator();
  142.       }
  143.       return metaBindingCreator;
  144.     }
  145. /** encapsulates lookup strategy to find an appropriate 
  146.    * BindingCreator for the given component. <p>
  147.    * 
  148.    * Here:
  149.    * <ol>
  150.    * <li> look-up by component class
  151.    * <li> look-up by assignables to component class
  152.    * </ol>
  153.    * 
  154.    *  
  155.    * @param component
  156.    * @return a BindingCreator which can create a binding to
  157.    *   the component or null if none is found.
  158.    */
  159.   protected BindingCreator getBindingCreator(JComponent component) {
  160.     // PENDING: implement better lookup...
  161.     BindingCreator creator =
  162.       (BindingCreator) getBindingMap().get(component.getClass());
  163.     if (creator == null) {
  164.       creator = findByAssignable(component.getClass());
  165.     }
  166.     return creator;
  167.   }
  168.   protected BindingCreator findByAssignable(Class componentClass) {
  169.     Set keys = getBindingMap().keySet();
  170.     for (Iterator iter = keys.iterator(); iter.hasNext(); ) {
  171.       Class element = (Class) iter.next();
  172.       if (element.isAssignableFrom(componentClass)) {
  173.         return (BindingCreator) getBindingMap().get(element);
  174.       }
  175.     }
  176.     return null;
  177.   }
  178.   protected Map getBindingMap() {
  179.     if (bindingMap == null) {
  180.       bindingMap = new HashMap();
  181.       initBindingMap(bindingMap);
  182.     }
  183.     return bindingMap;
  184.   }
  185.   protected void initBindingMap(Map map) {
  186.     map.put(JXHyperlink.class, new HyperlinkBindingCreator());  
  187.     map.put(JXRadioGroup.class, new RadioGroupBindingCreator());
  188.     map.put(JLabel.class, new LabelBindingCreator());
  189.     map.put(JCheckBox.class, new CheckBoxBindingCreator());
  190.     BindingCreator textBindingCreator = new TextBindingCreator();
  191.     map.put(JTextComponent.class, textBindingCreator);
  192.     map.put(JComboBox.class, new ComboBoxBindingCreator());
  193.     BindingCreator tableBindingCreator = new TableBindingCreator();
  194.     map.put(JTable.class, tableBindingCreator);
  195.     BindingCreator listBindingCreator = new ListBindingCreator();
  196.     map.put(JList.class, listBindingCreator);
  197.     map.put(JSpinner.class, new SpinnerBindingCreator());
  198.     map.put(JXImagePanel.class, new ImagePanelBindingCreator());
  199.     map.put(JXDatePicker.class, new DatePickerBindingCreator());
  200.   }
  201. //-------------------------------- BindingCreators  
  202.   /**
  203.    */
  204.   public static class ListBindingCreator implements BindingCreator {
  205.     public Binding createBinding(JComponent component, DataModel dataModel,
  206.         String fieldName) {
  207.       return new ListBinding((JList) component, dataModel, fieldName);
  208.       
  209.     }
  210.   }
  211.   /**
  212.    */
  213.   public class TableBindingCreator implements BindingCreator {
  214.     public Binding createBinding(JComponent component, DataModel dataModel,
  215.         String fieldName) {
  216.       return new TableBinding((JTable) component, dataModel, fieldName);
  217.     }
  218.   }
  219.   /**
  220.    */
  221.   public static class TextBindingCreator implements BindingCreator {
  222.     public Binding createBinding(JComponent component, DataModel dataModel,
  223.         String fieldName) {
  224.       Binding binding = doCreateBinding((JTextComponent) component,
  225.                           dataModel, fieldName);
  226. //      configureComponent(component, binding);
  227.       return binding;
  228.     }
  229.     protected Binding doCreateBinding(JTextComponent component,
  230.         DataModel dataModel, String fieldName) {
  231.       Binding binding = new TextBinding(component, dataModel, fieldName);
  232.       return binding;
  233.     }
  234.     /**
  235.      * PENDING: it's a view issue, should not be done here?.
  236.      * @param component
  237.      * @param binding
  238.      */
  239.     protected void configureComponent(JComponent component, Binding binding) {
  240.       int iconPosition = (component instanceof JTextArea)
  241.                            ? SwingConstants.NORTH_EAST : SwingConstants.WEST;
  242. //      BindingBorder bborder = new BindingBorder(binding, iconPosition);
  243. ////      Insets insets = bborder.getBorderInsets(component);
  244. ////      Dimension prefSize = component.getPreferredSize();
  245. ////      prefSize.width += (insets.left + insets.right);
  246. ////      // JW: arrgghhh... never do, prevents correct resizing.
  247. ////      component.setPreferredSize(prefSize);
  248. //      component.setBorder(new CompoundBorder(component.getBorder(), bborder));
  249.     }
  250.   }
  251.   /**
  252.    */
  253.   public static class LabelBindingCreator implements BindingCreator {
  254.     public Binding createBinding(JComponent component, DataModel dataModel,
  255.         String fieldName) {
  256.       return new LabelBinding((JLabel) component, dataModel, fieldName);
  257.     }
  258.   }
  259.   /**
  260.    */
  261.   public static class ImagePanelBindingCreator implements BindingCreator {
  262.     public Binding createBinding(JComponent component, DataModel dataModel,
  263.         String fieldName) {
  264.       return new ImagePanelBinding((JXImagePanel) component, dataModel, fieldName);
  265.     }
  266.   }
  267.   /**
  268.    */
  269.   public static class HyperlinkBindingCreator implements BindingCreator {
  270.     public Binding createBinding(JComponent component, DataModel dataModel,
  271.         String fieldName) {
  272.       return new HyperlinkBinding((JButton) component, dataModel, fieldName);
  273.     }
  274.   }
  275.   /**
  276.    */
  277.   public static class DatePickerBindingCreator implements BindingCreator {
  278.     public Binding createBinding(JComponent component, DataModel dataModel,
  279.         String fieldName) {
  280.       return new DatePickerBinding((JXDatePicker) component, dataModel, fieldName);
  281.     }
  282.   }
  283.   /**
  284.    */
  285.   public static abstract class RequiredBindingCreator implements BindingCreator {
  286.     protected void doAddBindingBorder(JComponent component, Binding binding) {
  287. //      component.setBorder(new CompoundBorder(new BindingBorder(binding),
  288. //          component.getBorder()));
  289.     }
  290.   }
  291.   /**
  292.    */
  293.   public static class ComboBoxBindingCreator extends RequiredBindingCreator {
  294.     public Binding createBinding(JComponent component, DataModel dataModel,
  295.         String fieldName) {
  296.       Binding binding = new ComboBoxBinding((JComboBox) component, dataModel,
  297.                           fieldName);
  298.       doAddBindingBorder(component, binding);
  299.       return binding;
  300.     }
  301.   }
  302.   /**
  303.    */
  304.   public static class RadioGroupBindingCreator extends RequiredBindingCreator {
  305.     public Binding createBinding(JComponent component, DataModel dataModel,
  306.         String fieldName) {
  307.       Binding binding = new RadioBinding((JXRadioGroup) component, dataModel,
  308.                           fieldName);
  309.       doAddBindingBorder(component, binding);
  310.       return binding;
  311.     }
  312.   }
  313.   /**
  314.    */
  315.   public static class CheckBoxBindingCreator extends RequiredBindingCreator {
  316.     public Binding createBinding(JComponent component, DataModel dataModel,
  317.         String fieldName) {
  318.       Binding binding = new BooleanBinding((JCheckBox) component, dataModel,
  319.                           fieldName);
  320.       doAddBindingBorder(component, binding);
  321.       return binding;
  322.     }
  323.   }
  324.   /**
  325.    */
  326.   public static class SpinnerBindingCreator extends RequiredBindingCreator {
  327.     public Binding createBinding(JComponent component, DataModel dataModel,
  328.         String fieldName) {
  329.       Binding binding = new SpinnerBinding((JSpinner) component, dataModel,
  330.                           fieldName);
  331.       doAddBindingBorder(component, binding);
  332.       return binding;
  333.     }
  334.   }
  335.   /**
  336.    * BindingCreator for binding a label to the metaData of the given field.
  337.    */
  338.   public class LabelMetaBindingCreator implements BindingCreator {
  339.       public Binding createBinding(JComponent component, DataModel dataModel,
  340.               String fieldName) {
  341.           if (component instanceof JLabel) {
  342.               return new LabelMetaBinding((JLabel) component, dataModel, fieldName);
  343.           }
  344.           return null;
  345.       }
  346.   }
  347. }