home *** CD-ROM | disk | FTP | other *** search
/ Symantec Visual Cafe for Java 2.5 / symantec-visual-cafe-2.5-database-dev-edition.iso / VCafe / prosrc.bin / ComboBox.java < prev    next >
Encoding:
Java Source  |  1998-03-18  |  23.4 KB  |  768 lines

  1. /*
  2.  * @(#ComboBox.java
  3.  *
  4.  * Copyright (c) 1997 Symantec Corporation. All Rights Reserved.
  5.  *
  6.  */
  7.  
  8.  
  9. package symantec.itools.db.awt;
  10.  
  11. import java.util.Vector;
  12. import java.util.Enumeration;
  13. import java.lang.*;
  14. import java.awt.event.*;
  15. import java.sql.SQLException;
  16. import symantec.itools.db.pro.*;
  17. import symantec.itools.db.beans.binding.Name;
  18. import symantec.itools.db.beans.binding.Mediator;
  19.  
  20. /**
  21.  * A dbAWARE ComboBox.
  22.  * <p>
  23.  * This component can be "bound" to a projection within a relation view
  24.  * so that it automatically gets and sets the values in that relation.
  25.  * <p>
  26.  */
  27. public class ComboBox extends symantec.itools.awt.ComboBox implements ListLink, ProjectionBean
  28. {
  29.     /**
  30.      * A constant value indicating how an empty string will be saved in the database.
  31.      */
  32.     public final static int Default    =  0;
  33.     /**
  34.      * A constant value indicating how an empty string will be saved in the database.
  35.      */
  36.     public final static int Null       =  1;
  37.     /**
  38.      * A constant value indicating how an empty string will be saved in the database.
  39.      */
  40.     public final static int Blank      =  2;
  41.  
  42.     /**
  43.      * Constant value for the Triggering Event property.
  44.      * Indicates the triggering event is ACTION_PERFORMED.
  45.      */
  46.     public static final int Action_Event=0;
  47.     /**
  48.      * Constant value for the Triggering Event property.
  49.      * Indicates the triggering event is FOCUS_LOST.
  50.      */
  51.     public static final int Focus_Event=1;
  52.     /**
  53.      * Constant value for the Triggering Event property.
  54.      * Indicates the triggering event is KEY_PRESSED.
  55.      */
  56.     public static final int Key_Event=2;
  57.     /**
  58.      * The  Binder object which this component can use to get data from
  59.      * the server, or change data at the database server.
  60.      */
  61.     /**
  62.      * The value of the Triggering Event property.
  63.      * The type of event that triggers this component to commit its changes.
  64.      * @see #getTriggeringEvent
  65.      * @see #setTriggeringEvent
  66.      * @see #Focus_Event
  67.      * @see #Key_Event
  68.      * @see #Action_Event
  69.      */
  70.     protected int TriggeringEvent=symantec.itools.db.awt.ProjectionBeanHelper.Focus_Event;
  71.     /**
  72.      * Controls when the component commits its changes.
  73.      * If <code>true</code>, this component sets the triggering event to
  74.      * Key_Event, otherwise the triggering event is set to Focus_Event.
  75.      * @see #getDynamicUpdate
  76.      * @see #setDynamicUpdate
  77.      * @see #Focus_Event
  78.      * @see #Key_Event
  79.      */
  80.     protected boolean m_DynamicUpdate=false;
  81.  
  82.     private ListBinder   m_ListBinder;
  83.  
  84.     private boolean m_IsBound = false;
  85.     private boolean m_autoExpand = true;
  86.     private boolean m_dynamicPopulate = false;
  87.  
  88.     private RelationView    m_LookUpRelationView;
  89.     private Vector          m_JoinColumns;
  90.     private ConnectionInfo  m_Conn;
  91.     private String          m_SQL;
  92.  
  93.     private Vector  staticItems = new Vector();
  94.     private Vector  allItems = new Vector();
  95.  
  96.     private ProjectionBeanHelper m_Helper;
  97.     private String IName;
  98.  
  99.     /**
  100.      * Constructs a new default ComboBox. The ComboBox is not editable and
  101.      * not searchable by default.
  102.      */
  103.     public ComboBox()
  104.     {
  105.         this(false, false);
  106.     }
  107.  
  108.     /**
  109.     * Constructs a new editable and/or searchable ComboBox.
  110.     * @param editable true = editable, false = non-editable
  111.     * @param searchable true = searchable, false = non-searchable
  112.     */
  113.     public ComboBox(boolean editable, boolean searchable)
  114.     {
  115.         super(editable, searchable);
  116.         m_JoinColumns = new Vector();
  117.         m_SQL = new String();
  118.         m_Helper = new ProjectionBeanHelper(this);
  119.         editBox.addFocusListener(m_Helper);
  120.     }
  121.  
  122.     /**
  123.      * Constructs a new ComboBox linked to a database. The ComboBox is not editable and
  124.      * not searchable by default.
  125.      *
  126.      * @param relView the relation view to bind with
  127.      * @param conn the information needed to connect to the database
  128.      */
  129.     public ComboBox(RelationView lookupRV, ConnectionInfo conn)
  130.     {
  131.         this();
  132.         m_LookUpRelationView = lookupRV;
  133.         m_Conn = conn;
  134.     }
  135.  
  136.     /**
  137.      * Called when this component has been bound to a RelationView.
  138.      * This component notes the ListBinder object so that it
  139.      * may notify the dbANYWHERE server of data changes made.
  140.      * <p>
  141.      * This is a method in the ListLink interface.
  142.      *
  143.      * @param lBinder used to notify the dbANYWHERE server of any data changes
  144.      * that are to be persistant.
  145.      *
  146.      * @see symantec.itools.db.pro.ListLink#init
  147.      */
  148.     public void init (ListBinder lBinder)
  149.     {
  150.         m_ListBinder = lBinder;
  151.     }
  152.  
  153.     /**
  154.      * This method is called to update the value of this dbAWARE component.
  155.      * It is called when the dbANYWHERE server has detected a data change made
  156.      * within the RelationView bound to this component.
  157.      * The ListBinder object passed into the notification is used to get the
  158.      * new data value.
  159.      * <p>
  160.      * This is a method in the ListLink interface.
  161.      *
  162.      * @param binder used to get the current value from the dbANYWHERE server.
  163.      *
  164.      * @see symantec.itools.db.pro.ListLink#notifyListChange
  165.      */
  166.     public void notifyListChange(ListBinder lBinder)
  167.     {
  168.         if (m_dynamicPopulate)
  169.         {
  170.             try
  171.             {
  172.                 clear();
  173.                 allItems.removeAllElements();
  174.  
  175.                 RelationView curRV = lBinder.getRelationView();
  176.                 while ( curRV.next() == true )
  177.                 {
  178.                     super.addItem( curRV.getStringValue(1) );
  179.                     allItems.addElement(curRV.getStringValue(1));
  180.                 }
  181.                 String ne;
  182.                 Enumeration e = staticItems.elements();
  183.                 while(e.hasMoreElements())
  184.                 {
  185.                     ne = (String)e.nextElement();
  186.                     super.addItem(ne);
  187.                     allItems.addElement(ne);
  188.                 }
  189.                 m_Helper.notifyDataChange();
  190.             }
  191.             catch (Exception Ex) {
  192.                 m_Helper.raiseException(Ex);
  193.             }
  194.         }
  195.     }
  196.  
  197.     private boolean searchList(String item)
  198.     {
  199.         boolean found = false;
  200.         String[] e=list.getListItems();
  201.         int size=e.length;
  202.         for(int i=0; i<size;i++)
  203.         {
  204.             if (e[i].equals(item))
  205.             {
  206.                 found = true;
  207.                 break;
  208.             }
  209.         }
  210.         return found;
  211.         
  212.     }
  213.  
  214.     /**
  215.      * Adds a column to the list of columns that this component will be bound
  216.      * to. Use this method before calling bindList().
  217.      *
  218.      * @param columnName the name of the column to join
  219.      * @exception SQLException
  220.      * if a SQL database access error occurred
  221.      * @see #bindList
  222.      */
  223.     public void join(String columnName) throws SQLException
  224.     {
  225.         int colID = m_LookUpRelationView.findProjByName(columnName);
  226.         if (m_JoinColumns == null)
  227.         {
  228.             m_JoinColumns = new Vector();
  229.         }
  230.         m_JoinColumns.addElement(new Integer(colID));
  231.     }
  232.  
  233.     /**
  234.      * Sets the sql string to use while generating the list for this component
  235.      * to bind to. Use this method before calling bindList().
  236.      *
  237.      * @param sql the sql string
  238.      * @exception SQLException
  239.      * if a SQL database access error occurred
  240.      *
  241.      * @see #bindList
  242.      */
  243.     public void setSQL(String sql) throws SQLException
  244.     {
  245.         m_SQL = sql;
  246.     }
  247.  
  248.     /**
  249.      * Binds this component to a list of columns within a RelationView.
  250.      * The RelationView and connection information to use is specified at
  251.      * construction time. The columns to use are specified using the join()
  252.      * method.
  253.      *
  254.      * @see #join
  255.      * @exception SQLException
  256.      * if a SQL database access error occurred
  257.      */
  258.     public void bindList() throws SQLException
  259.     {
  260.         m_dynamicPopulate = true;
  261.         m_LookUpRelationView.bindList(m_Conn, m_SQL, this, m_JoinColumns);
  262.     }
  263.  
  264.     /**
  265.      * Adds the specified item to the end of drop-down list and enable the item.
  266.      * @param item the item to be added
  267.      * @see #setListItems(java.lang.String[])
  268.      */
  269.     public synchronized void addItem(String item) {
  270.         try {
  271.             super.addItem(item);
  272.         }
  273.         catch (java.beans.PropertyVetoException ex) {
  274.         }
  275.         staticItems.addElement(item);
  276.         if (m_dynamicPopulate) {
  277.             allItems.addElement(item);
  278.         }
  279.     }
  280.  
  281.     /**
  282.      * Sets whether to automatically add items onto the end of this list when
  283.      * they are added to the database.
  284.      *
  285.      * @param ae true to auto-expand, false otherwise
  286.      * @see #getAutoExpand
  287.      */
  288.     public void setAutoExpand(boolean ae)
  289.     {
  290.         m_autoExpand = ae;
  291.         if (m_autoExpand) {
  292.             m_Helper.notifyDataChange();    // In case we're just starting up
  293.                                             // and we've been bound; but, we
  294.                                             // weren't autoExpanded so we
  295.                                             // lost one
  296.         }
  297.     }
  298.  
  299.     /**
  300.      * Gets whether to automatically add items onto the end of this list when
  301.      * they are added to the database.
  302.      *
  303.      * @return true if auto-expands, false otherwise
  304.      * @see #setAutoExpand
  305.      */
  306.     public boolean getAutoExpand() {
  307.         return m_autoExpand;
  308.     }
  309.  
  310.     /**
  311.      * Adds the string array to the list.
  312.      * @param items items to add to the list
  313.      * @see #addItem(java.lang.String)
  314.      * @exception java.beans.PropertyVetoException if the specified property value is unacceptable
  315.      */
  316.     public void setListItems(String[] listItems) throws java.beans.PropertyVetoException
  317.     {
  318.         String[] currentItems = getListItems();
  319.         if (currentItems.length == 0)
  320.         {
  321.             clear();
  322.         }
  323.         for (int i = 0; i < listItems.length; ++i)
  324.         {
  325.             staticItems.addElement(listItems[i]);
  326.             super.addItem(listItems[i]);
  327.         }
  328.         if(IName!=null)m_Helper.setDataBinding(new Name(IName));
  329.  
  330.     }
  331.  
  332.     /**
  333.      * Binds this component to a given projection within the specified
  334.      * relation view.
  335.      *
  336.      * @param relView the relation view to bind with
  337.      * @param projection the projection in relView to bind with
  338.      */
  339.     public void setBinding(RelationView relView, String projection)
  340.     {
  341.         m_Helper.setBinding(relView, projection);
  342.     }
  343.  
  344.     /**
  345.      * Returns the projection in the RelationView that this component is bound with.
  346.      * @see #setProjection
  347.      * @see #setBinding
  348.      */
  349.     public String getProjection() {
  350.         return m_Helper.getProjection();
  351.     }
  352.  
  353.     /**
  354.      * Sets the projection in the RelationView that this component is bound with.
  355.      * @param projection the name of the projection
  356.      * @see #getProjection
  357.      * @see #setBinding
  358.      */
  359.     public void setProjection(String projection) {
  360.         m_Helper.setProjection(projection);
  361.         m_IsBound = true;
  362.     }
  363.  
  364.     /**
  365.      * Gets the RelationView that this component is bound with.
  366.      * @return the RelationView
  367.      * @see #setRelationView
  368.      * @see #setBinding
  369.      */
  370.     public RelationView getRelationView() {
  371.         return m_Helper.getRelationView();
  372.     }
  373.  
  374.     /**
  375.      * Sets the RelationView that this component is bound with.
  376.      * @param rv the new RelationView to bind with
  377.      * @see #getRelationView
  378.      * @see #setBinding
  379.      */
  380.     public void setRelationView(RelationView rv) {
  381.         m_Helper.setRelationView(rv);
  382.         m_IsBound = true;
  383.     }
  384.  
  385.     /**
  386.      * Specifies how an empty string will be set when updating data on
  387.      * the dbANYWHERE server.
  388.      *
  389.      * @param blank one of "DEFAULT", "NULL", or "BLANK"
  390.      *
  391.      * @see symantec.itools.db.pro.ProjBinder#setValueFromString(java.lang.String, int, int)
  392.      */
  393.  
  394.     public void setTreatBlankAs(int value) {
  395.         m_Helper.setTreatBlankAs(value);
  396.     }
  397.  
  398.     /**
  399.      * Indicates when the component commits its changes.
  400.      * If <code>true</code>, this component has set the triggering event to
  401.      * Key_Event, otherwise the triggering event is set to Focus_Event.
  402.      * @see #setDynamicUpdate
  403.      * @see #Focus_Event
  404.      * @see #Key_Event
  405.      */
  406.     public boolean getDynamicUpdate() {
  407.        return m_DynamicUpdate;
  408.     }
  409.  
  410.     /**
  411.      * Sets when the component commits its changes.
  412.      * If <code>true</code>, this component sets the triggering event to
  413.      * Key_Event, otherwise the triggering event is set to Focus_Event.
  414.      * @param value the new dynamic update mode value
  415.      * @see #getDynamicUpdate
  416.      * @see #Focus_Event
  417.      * @see #Key_Event
  418.      */
  419.     public void setDynamicUpdate(boolean value) {
  420.  
  421.          if(value==true){
  422.            this.setTriggeringEvent(symantec.itools.db.awt.ProjectionBeanHelper.Key_Event);
  423.         }
  424.         if(value==false){
  425.            this.setTriggeringEvent(symantec.itools.db.awt.ProjectionBeanHelper.Focus_Event);
  426.         }
  427.         m_DynamicUpdate = value;
  428.     }
  429.  
  430.     /**
  431.      * Sets whether the data value of this component may be modified.
  432.      * @param value <code>true</code> if the value may not be modified,
  433.      * <code>false</code>if the value may be modified
  434.      */
  435.     public void setReadOnly(boolean value) {
  436.         try {
  437.             setEditable(!value);
  438.         }
  439.         catch (Exception ex) {
  440.             m_Helper.raiseException(ex);
  441.         }
  442.     }
  443.  
  444.     /**
  445.      * Sets the value of this component to the given value.
  446.      * @param value the new component value
  447.      * @see #getData
  448.      */
  449.      String text;
  450.     public void setData(Object value) {
  451.         text = value.toString();
  452.         try {
  453.             list.deselectAll();
  454.             if (((staticItems.size() > 0) || (m_IsBound && allItems.size() > 0)) && searchList(text)) {
  455.                 super.select(text);
  456.             }
  457.             
  458.             else if (m_autoExpand && text!="") 
  459.                 {
  460.                     if(!uniqueElements){
  461.                        super.addItem(text);
  462.                        }
  463.                     staticItems.addElement(text);
  464.                   }
  465.                   
  466.              if(searchList(text)){
  467.                 super.select(text);
  468.              }
  469.            
  470.           editBox.setText(text);
  471.         }
  472.        
  473.         catch (java.beans.PropertyVetoException ex) {
  474.         }
  475.     }
  476.     
  477.  
  478.     /**
  479.      * Gets the value of this component.
  480.      * @return the current component value
  481.      * @see #setData
  482.      */
  483.     public Object getData() {
  484.         if(!isSearchable()){
  485.             text = getText();
  486.             return text;
  487.         }
  488.         else {
  489.             text=getSelectedItem();
  490.             editBox.setText(text);
  491.             return(text);
  492.         }
  493.  
  494.     }
  495.  
  496.     /**
  497.      * Gets whether this component saves its value as a text String.
  498.      * @return <code>true</code> if the value is saved as text,
  499.      * <code>false</code> otherwise
  500.      */
  501.     public boolean isTextBased() {
  502.         return true;
  503.     }
  504.  
  505.     /**
  506.      * Gets the number of digits to the right of the decimal point for
  507.      * this component's value.
  508.      * @return the number of digits to the right of the decimal point
  509.      */
  510.     public int getScale() {
  511.         return ProjBinder.DEFAULTSCALE;
  512.     }
  513.  
  514.     /**
  515.      * Registers the standard event listener(s) for this component.
  516.      */
  517.     public void registerListeners() {
  518.         editBox.addKeyListener(m_Helper);
  519.         // editBox.addTextListener(m_Helper);
  520.         addActionListener(m_Helper);
  521.     }
  522.     /**
  523.      * Sets the name of the data item to bind this component to.
  524.      * @param name the data item name, like "MyTable@MyColumn"
  525.      * @see #getDataBinding
  526.      */
  527.     public void setDataBinding(String name)
  528.     {
  529.         IName=name;
  530.         m_Helper.setDataBinding(new Name(IName));
  531.     }
  532.  
  533.     /**
  534.      * Gets the name of the data item this component is bound to.
  535.      * @returns the data item name, like "MyTable@MyColumn"
  536.      * @see #setDataBinding
  537.      */
  538.     public String getDataBinding()
  539.     {
  540.         return  m_Helper.getDataBinding().getFullName();
  541.     }
  542.     void removeAllListeners()
  543.     {
  544.         editBox.removeFocusListener(m_Helper);
  545.         editBox.removeActionListener(m_Helper);
  546.         editBox.removeKeyListener(m_Helper);
  547.     }
  548.     /**
  549.      * Sets the value of the Triggering Event property.
  550.      * This determines the type of event that triggers the component to commit
  551.      * its changes to the database.
  552.      * @param event one of Focus_Event, Action_Event, or Key_Event
  553.      * @see #getTriggeringEvent
  554.      * @see #Focus_Event
  555.      * @see #Action_Event
  556.      * @see #Key_Event
  557.      */
  558.     public void setTriggeringEvent(int Event)
  559.     {
  560.         TriggeringEvent=Event;
  561.         this.removeAllListeners();
  562.         switch(Event){
  563.             case symantec.itools.db.awt.ProjectionBeanHelper.Focus_Event:
  564.             editBox.addFocusListener(m_Helper);
  565.             break;
  566.             case symantec.itools.db.awt.ProjectionBeanHelper.Action_Event:
  567.             editBox.addActionListener(m_Helper);
  568.             break;
  569.             case symantec.itools.db.awt.ProjectionBeanHelper.Key_Event:
  570.             editBox.addKeyListener(m_Helper);
  571.             break;
  572.             default:
  573.             editBox.addFocusListener(m_Helper);
  574.        }
  575.     }
  576.     /**
  577.      * Gets the current value of the Triggering Event property.
  578.      * This determines the type of event that triggers the component to commit
  579.      * its changes to the database.
  580.      * @return one of Focus_Event, Action_Event, or Key_Event
  581.      * @see #setTriggeringEvent
  582.      * @see #Focus_Event
  583.      * @see #Action_Event
  584.      * @see #Key_Event
  585.      */
  586.     public int getTriggeringEvent()
  587.     {
  588.         return TriggeringEvent;
  589.     }
  590.     protected void sourceActionEvent(String command)
  591.     {
  592.         super.sourceActionEvent( command);
  593.         m_Helper.m_Mediator.commit();
  594.      }
  595.  
  596.     Mediator m_LookupMediator;
  597.     Name lookupName=new Name();
  598.     private String[] m_GetMethods={"getDataAt(row)"};
  599.     private String[] m_SetMethods={"setDataAtIf(row,Value)"};
  600.     private String[] m_SetMethodsII={"setDataAt(row,Value)"};
  601.     private boolean isLookup=false;
  602.  
  603.     /**
  604.      * Sets the value of the Lookup Name property.
  605.      * This property is the name of a data source table and column.
  606.      * It is used to fill this component with data.
  607.      * @param lame the new lookup name
  608.      * @see #getLookupName
  609.      */
  610.      boolean uniqueElements=false;
  611.      public void setUniqueElements(boolean a)
  612.      {
  613.         uniqueElements=a;
  614.      }
  615.      public boolean getUniqueElements()
  616.      {
  617.         return uniqueElements;
  618.      }
  619.     public void setLookupName(String lname)
  620.     {   
  621.         Name name = new Name(lname);
  622.         isLookup=true;
  623.         
  624.          boolean ae=getAutoExpand();
  625.         if(m_LookupMediator==null){
  626.             m_LookupMediator =new symantec.itools.db.beans.binding.Mediator() ;
  627.             m_LookupMediator.setOutput(this);
  628.             if(uniqueElements)m_LookupMediator.setSetMethods(m_SetMethods);
  629.             else 
  630.             {
  631.                 setAutoExpand(true);
  632.                 m_LookupMediator.setSetMethods(m_SetMethodsII);
  633.                }
  634.  
  635.             }
  636.         if(name.getNumberOfRows()==1)name.setNumberOfRows(-1);
  637.         lookupName=name;
  638.         m_LookupMediator.setDataBinding(name.getFullName());
  639.         setAutoExpand(ae);
  640.         arrow.setEnabled(true);
  641.         if(IName!=null)m_Helper.setDataBinding(new Name(IName));
  642.          
  643.  
  644.     }
  645.     /**
  646.      * Gets the value of the Lookup Name property.
  647.      * This property is the name of a data source table and column.
  648.      * It is used to fill this component with data.
  649.      * @return the property value
  650.      * @see #setLookupName
  651.      */
  652.     public String getLookupName()
  653.     {
  654.         return lookupName.getFullName();
  655.     }
  656.  
  657.     /**
  658.      * Sets the value stored at a particular row.
  659.      * @param row the zero-relative row index
  660.      * @param value the new value
  661.      * @see #getDataAt
  662.      */
  663.      int currentItems=0;
  664.        Object oldValue;
  665.        String Value;
  666.     public void setDataAt(int row,Object value)
  667.     { 
  668.         int totalItems=countItems();
  669.         int newNumberRows=m_LookupMediator.getOutputSize().height;
  670.         try{
  671.             if(currentItems>newNumberRows)
  672.             {
  673.                 for(int r=newNumberRows;r<currentItems;r++)
  674.                 {
  675.                 list.delItem(0);
  676.                 }
  677.             currentItems=newNumberRows;
  678.             totalItems=newNumberRows;
  679.             }
  680.             if(row >=totalItems)
  681.             {
  682.                 for(int i=totalItems;i<=row ;i++)
  683.                 {
  684.                     list.addItem(" ");
  685.                 }
  686.             }    
  687.             if(value==null)value="";
  688.             Value=value.toString();
  689.             if(!getItem(row).equals(Value))list.setText(row, Value);
  690.             currentItems=newNumberRows;
  691.             
  692.             oldValue=text;
  693.             if(oldValue!=null)
  694.             {
  695.                if( oldValue.equals(Value) && !Value.equals(""))  
  696.                 {
  697.                    super.select(Value);
  698.                    // editBox.setText(text);
  699.                 }
  700.                 
  701.             }
  702.         }catch(java.beans.PropertyVetoException e){}     
  703.     }
  704.     /**
  705.      * Sets the value stored at a particular row if it is
  706.      * not equal to the current value.
  707.      * @param row the zero-relative row index
  708.      * @param value the new value
  709.      * @see #getDataAt
  710.      */
  711.     
  712.     public void setDataAtIf(int row,Object value)
  713.     {
  714.         int totalItems=countItems();
  715.         
  716.         if(value!=null && value!="")
  717.         {
  718.         for(int i=0;i<totalItems ;i++)
  719.             {
  720.                 if(getItem(i).toString().equals(value.toString()))return;
  721.             }
  722.             addItem(value.toString());
  723.              
  724.         }
  725.         // currentItems=newNumberRows;
  726.     }
  727.     /**
  728.      * Gets the value stored at a particular row.
  729.      * @param row the zero-relative row index
  730.      * @return the value
  731.      * @see #setDataAt
  732.      */
  733.     public Object getDataAt(int row)
  734.     {
  735.         int totalItems=countItems();
  736.         if(row<totalItems)return (Object)list.getItem(row);
  737.         return "";
  738.     }
  739.  
  740.      /**
  741.      * Sets the value of the Empty Means Null property.
  742.      * This determines how an empty string will be saved when updating data on
  743.      * the database server.
  744.      * A value of <code>true</code>indicates an empty string will be saved as a
  745.      * SQL NULL value. Otherwise it will be saved as a blank value.
  746.      * @param propertyValue <code>true</code> for NULL, <code>false</code> for BLANK
  747.      * @see #getEmptyMeansNull
  748.      */
  749.     public void setEmptyMeansNull(boolean propertyValue)
  750.     {
  751.         m_Helper.setEmptyMeansNull(propertyValue);
  752.     }
  753.  
  754.      /**
  755.      * Gets the value of the Empty Means Null property.
  756.      * This determines how an empty string will be saved when updating data on
  757.      * the database server.
  758.      * A value of <code>true</code>indicates an empty string will be saved as a
  759.      * SQL NULL value. Otherwise it will be saved as a blank value.
  760.      * @return <code>true</code> for NULL, <code>false</code> for BLANK
  761.      * @see #setEmptyMeansNull
  762.      */
  763.     public boolean getEmptyMeansNull()
  764.     {
  765.         return m_Helper.getEmptyMeansNull();
  766.     }
  767. }
  768.