]> source.dussan.org Git - vaadin-framework.git/commitdiff
fixed bad code code style
authorMatti Tahvonen <matti.tahvonen@itmill.com>
Thu, 15 May 2008 12:44:09 +0000 (12:44 +0000)
committerMatti Tahvonen <matti.tahvonen@itmill.com>
Thu, 15 May 2008 12:44:09 +0000 (12:44 +0000)
svn changeset:4509/svn branch:trunk

src/com/itmill/toolkit/ui/AbstractField.java

index f067cd961e57df661fb0a86d3ba412d54182de53..7fef394a976bb0cb8762c4469bfa277409680529 100644 (file)
@@ -49,927 +49,931 @@ import com.itmill.toolkit.terminal.PaintTarget;
  * @since 3.0
  */
 public abstract class AbstractField extends AbstractComponent implements Field,
-               Property.ReadOnlyStatusChangeNotifier {
-
-       /* Private members ************************************************* */
-
-       private boolean delayedFocus;
-
-       /**
-        * Value of the datafield.
-        */
-       private Object value;
-
-       /**
-        * Connected data-source.
-        */
-       private Property dataSource = null;
-
-       /**
-        * The list of validators.
-        */
-       private LinkedList validators = null;
-
-       /**
-        * Auto commit mode.
-        */
-       private boolean writeTroughMode = true;
-
-       /**
-        * Reads the value from data-source, when it is not modified.
-        */
-       private boolean readTroughMode = true;
-
-       /**
-        * Is the field modified but not committed.
-        */
-       private boolean modified = false;
-
-       /**
-        * Current source exception.
-        */
-       private Buffered.SourceException currentBufferedSourceException = null;
-
-       /**
-        * Are the invalid values alloved in fields ?
-        */
-       private boolean invalidAllowed = true;
-
-       /**
-        * Are the invalid values committed ?
-        */
-       private boolean invalidCommitted = false;
-
-       /**
-        * The tab order number of this field.
-        */
-       private int tabIndex = 0;
-
-       /**
-        * Required field.
-        */
-       private boolean required = false;
-
-       /* Component basics ************************************************ */
-
-       /*
-        * Paints the field. Don't add a JavaDoc comment here, we use the default
-        * documentation from the implemented interface.
-        */
-       public void paintContent(PaintTarget target) throws PaintException {
-
-               // The tab ordering number
-               if (tabIndex > 0) {
-                       target.addAttribute("tabindex", tabIndex);
-               }
-
-               // If the field is modified, but not committed, set modified attribute
-               if (isModified()) {
-                       target.addAttribute("modified", true);
-               }
-
-               // Adds the required attribute
-               if (isRequired()) {
-                       target.addAttribute("required", true);
-               }
-       }
-
-       /*
-        * Gets the field type Don't add a JavaDoc comment here, we use the default
-        * documentation from the implemented interface.
-        */
-       public abstract Class getType();
-
-       /**
-        * The abstract field is read only also if the data source is in readonly
-        * mode.
-        */
-       public boolean isReadOnly() {
-               return super.isReadOnly()
-                               || (dataSource != null && dataSource.isReadOnly());
-       }
-
-       /**
-        * Changes the readonly state and throw read-only status change events.
-        * 
-        * @see com.itmill.toolkit.ui.Component#setReadOnly(boolean)
-        */
-       public void setReadOnly(boolean readOnly) {
-               super.setReadOnly(readOnly);
-               fireReadOnlyStatusChange();
-       }
-
-       /**
-        * Tests if the invalid data is committed to datasource.
-        * 
-        * @see com.itmill.toolkit.data.BufferedValidatable#isInvalidCommitted()
-        */
-       public boolean isInvalidCommitted() {
-               return invalidCommitted;
-       }
-
-       /**
-        * Sets if the invalid data should be committed to datasource.
-        * 
-        * @see com.itmill.toolkit.data.BufferedValidatable#setInvalidCommitted(boolean)
-        */
-       public void setInvalidCommitted(boolean isCommitted) {
-               invalidCommitted = isCommitted;
-       }
-
-       /*
-        * Saves the current value to the data source Don't add a JavaDoc comment
-        * here, we use the default documentation from the implemented interface.
-        */
-       public void commit() throws Buffered.SourceException {
-               if (dataSource != null && (isInvalidCommitted() || isValid())
-                               && !dataSource.isReadOnly()) {
-                       final Object newValue = getValue();
-                       try {
-
-                               // Commits the value to datasource.
-                               dataSource.setValue(newValue);
-
-                       } catch (final Throwable e) {
-
-                               // Sets the buffering state.
-                               currentBufferedSourceException = new Buffered.SourceException(
-                                               this, e);
-                               requestRepaint();
-
-                               // Throws the source exception.
-                               throw currentBufferedSourceException;
-                       }
-               }
-
-               boolean repaintNeeded = false;
-
-               // The abstract field is not modified anymore
-               if (modified) {
-                       modified = false;
-                       repaintNeeded = true;
-               }
-
-               // If successful, remove set the buffering state to be ok
-               if (currentBufferedSourceException != null) {
-                       currentBufferedSourceException = null;
-                       repaintNeeded = true;
-               }
-
-               if (repaintNeeded) {
-                       requestRepaint();
-               }
-       }
-
-       /*
-        * Updates the value from the data source. Don't add a JavaDoc comment here,
-        * we use the default documentation from the implemented interface.
-        */
-       public void discard() throws Buffered.SourceException {
-               if (dataSource != null) {
-
-                       // Gets the correct value from datasource
-                       Object newValue;
-                       try {
-
-                               // Discards buffer by overwriting from datasource
-                               newValue = dataSource.getValue();
-
-                               // If successful, remove set the buffering state to be ok
-                               if (currentBufferedSourceException != null) {
-                                       currentBufferedSourceException = null;
-                                       requestRepaint();
-                               }
-                       } catch (final Throwable e) {
-
-                               // Sets the buffering state
-                               currentBufferedSourceException = new Buffered.SourceException(
-                                               this, e);
-                               requestRepaint();
-
-                               // Throws the source exception
-                               throw currentBufferedSourceException;
-                       }
-
-                       final boolean wasModified = isModified();
-                       modified = false;
-
-                       // If the new value differs from the previous one
-                       if ((newValue == null && value != null)
-                                       || (newValue != null && !newValue.equals(value))) {
-                               setInternalValue(newValue);
-                               fireValueChange(false);
-                       }
-
-                       // If the value did not change, but the modification status did
-                       else if (wasModified) {
-                               requestRepaint();
-                       }
-               }
-       }
-
-       /*
-        * Has the field been modified since the last commit()? Don't add a JavaDoc
-        * comment here, we use the default documentation from the implemented
-        * interface.
-        */
-       public boolean isModified() {
-               return modified;
-       }
-
-       /*
-        * Tests if the field is in write-through mode. Don't add a JavaDoc comment
-        * here, we use the default documentation from the implemented interface.
-        */
-       public boolean isWriteThrough() {
-               return writeTroughMode;
-       }
-
-       /*
-        * Sets the field's write-through mode to the specified status Don't add a
-        * JavaDoc comment here, we use the default documentation from the
-        * implemented interface.
-        */
-       public void setWriteThrough(boolean writeTrough)
-                       throws Buffered.SourceException {
-               if (writeTroughMode == writeTrough) {
-                       return;
-               }
-               writeTroughMode = writeTrough;
-               if (writeTroughMode) {
-                       commit();
-               }
-       }
-
-       /*
-        * Tests if the field is in read-through mode. Don't add a JavaDoc comment
-        * here, we use the default documentation from the implemented interface.
-        */
-       public boolean isReadThrough() {
-               return readTroughMode;
-       }
-
-       /*
-        * Sets the field's read-through mode to the specified status Don't add a
-        * JavaDoc comment here, we use the default documentation from the
-        * implemented interface.
-        */
-       public void setReadThrough(boolean readTrough)
-                       throws Buffered.SourceException {
-               if (readTroughMode == readTrough) {
-                       return;
-               }
-               readTroughMode = readTrough;
-               if (!isModified() && readTroughMode && dataSource != null) {
-                       setInternalValue(dataSource.getValue());
-                       fireValueChange(false);
-               }
-       }
-
-       /* Property interface implementation ******************************* */
-
-       /**
-        * Returns the value of the Property in human readable textual format.
-        * 
-        * @see java.lang.Object#toString()
-        */
-       public String toString() {
-               final Object value = getValue();
-               if (value == null) {
-                       return null;
-               }
-               return getValue().toString();
-       }
-
-       /**
-        * Gets the current value of the field. This is the visible, modified and
-        * possible invalid value the user have entered to the field. In the
-        * read-through mode, the abstract buffer is also updated and validation is
-        * performed.
-        * 
-        * @return the current value of the field.
-        */
-       public Object getValue() {
-
-               // Give the value from abstract buffers if the field if possible
-               if (dataSource == null || !isReadThrough() || isModified()) {
-                       return value;
-               }
-
-               final Object newValue = dataSource.getValue();
-               if ((newValue == null && value != null)
-                               || (newValue != null && !newValue.equals(value))) {
-                       setInternalValue(newValue);
-                       fireValueChange(false);
-               }
-
-               return newValue;
-       }
-
-       /**
-        * Sets the value of the field.
-        * 
-        * @param newValue
-        *            the New value of the field.
-        * @throws Property.ReadOnlyException
-        * @throws Property.ConversionException
-        */
-       public void setValue(Object newValue) throws Property.ReadOnlyException,
-                       Property.ConversionException {
-               setValue(newValue, false);
-       }
-
-       /**
-        * Sets the value of the field.
-        * 
-        * @param newValue
-        *            the New value of the field.
-        * @param repaintIsNotNeeded
-        *            True iff caller is sure that repaint is not needed.
-        * @throws Property.ReadOnlyException
-        * @throws Property.ConversionException
-        */
-       protected void setValue(Object newValue, boolean repaintIsNotNeeded)
-                       throws Property.ReadOnlyException, Property.ConversionException {
-
-               if ((newValue == null && value != null)
-                               || (newValue != null && !newValue.equals(value))) {
-
-                       // Read only fields can not be changed
-                       if (isReadOnly()) {
-                               throw new Property.ReadOnlyException();
-                       }
-
-                       // If invalid values are not allowed, the value must be checked
-                       if (!isInvalidAllowed()) {
-                               final Collection v = getValidators();
-                               if (v != null) {
-                                       for (final Iterator i = v.iterator(); i.hasNext();) {
-                                               ((Validator) i.next()).validate(newValue);
-                                       }
-                               }
-                       }
-
-                       // Changes the value
-                       setInternalValue(newValue);
-                       modified = dataSource != null;
-
-                       // In write trough mode , try to commit
-                       if (isWriteThrough() && dataSource != null
-                                       && (isInvalidCommitted() || isValid())) {
-                               try {
-
-                                       // Commits the value to datasource
-                                       dataSource.setValue(newValue);
-
-                                       // The buffer is now unmodified
-                                       modified = false;
-
-                               } catch (final Throwable e) {
-
-                                       // Sets the buffering state
-                                       currentBufferedSourceException = new Buffered.SourceException(
-                                                       this, e);
-                                       requestRepaint();
-
-                                       // Throws the source exception
-                                       throw currentBufferedSourceException;
-                               }
-                       }
-
-                       // If successful, remove set the buffering state to be ok
-                       if (currentBufferedSourceException != null) {
-                               currentBufferedSourceException = null;
-                               requestRepaint();
-                       }
-
-                       // Fires the value change
-                       fireValueChange(repaintIsNotNeeded);
-               }
-       }
-
-       /* External data source ******************************************** */
-
-       /**
-        * Gets the current data source of the field, if any.
-        * 
-        * @return the current data source as a Property, or <code>null</code> if
-        *         none defined.
-        */
-       public Property getPropertyDataSource() {
-               return dataSource;
-       }
-
-       /**
-        * <p>
-        * Sets the specified Property as the data source for the field. All
-        * uncommitted changes to the field are discarded and the value is refreshed
-        * from the new data source.
-        * </p>
-        * 
-        * <p>
-        * If the datasource has any validators, the same validators are added to
-        * the field. Because the default behavior of the field is to allow invalid
-        * values, but not to allow committing them, this only adds visual error
-        * messages to fields and do not allow committing them as long as the value
-        * is invalid. After the value is valid, the error message is not shown and
-        * the commit can be done normally.
-        * </p>
-        * 
-        * @param newDataSource
-        *            the new data source Property.
-        */
-       public void setPropertyDataSource(Property newDataSource) {
-
-               // Saves the old value
-               final Object oldValue = value;
-
-               // Discards all changes to old datasource
-               try {
-                       discard();
-               } catch (final Buffered.SourceException ignored) {
-               }
-
-               // Stops listening the old data source changes
-               if (dataSource != null
-                               && Property.ValueChangeNotifier.class
-                                               .isAssignableFrom(dataSource.getClass())) {
-                       ((Property.ValueChangeNotifier) dataSource).removeListener(this);
-               }
-
-               // Sets the new data source
-               dataSource = newDataSource;
-
-               // Gets the value from source
-               try {
-                       if (dataSource != null) {
-                               setInternalValue(dataSource.getValue());
-                       }
-                       modified = false;
-               } catch (final Throwable e) {
-                       currentBufferedSourceException = new Buffered.SourceException(this,
-                                       e);
-                       modified = true;
-               }
-
-               // Listens the new data source if possible
-               if (dataSource instanceof Property.ValueChangeNotifier) {
-                       ((Property.ValueChangeNotifier) dataSource).addListener(this);
-               }
-
-               // Copy the validators from the data source
-               if (dataSource instanceof Validatable) {
-                       final Collection validators = ((Validatable) dataSource)
-                                       .getValidators();
-                       if (validators != null) {
-                               for (final Iterator i = validators.iterator(); i.hasNext();) {
-                                       addValidator((Validator) i.next());
-                               }
-                       }
-               }
-
-               // Fires value change if the value has changed
-               if ((value != oldValue)
-                               && ((value != null && !value.equals(oldValue)) || value == null)) {
-                       fireValueChange(false);
-               }
-       }
-
-       /* Validation ****************************************************** */
-
-       /**
-        * Adds a new validator for the field's value. All validators added to a
-        * field are checked each time the its value changes.
-        * 
-        * @param validator
-        *            the new validator to be added.
-        */
-       public void addValidator(Validator validator) {
-               if (validators == null) {
-                       validators = new LinkedList();
-               }
-               validators.add(validator);
-       }
-
-       /**
-        * Gets the validators of the field.
-        * 
-        * @return the Unmodifiable collection that holds all validators for the
-        *         field.
-        */
-       public Collection getValidators() {
-               if (validators == null || validators.isEmpty()) {
-                       return null;
-               }
-               return Collections.unmodifiableCollection(validators);
-       }
-
-       /**
-        * Removes the validator from the field.
-        * 
-        * @param validator
-        *            the validator to remove.
-        */
-       public void removeValidator(Validator validator) {
-               if (validators != null) {
-                       validators.remove(validator);
-               }
-       }
-
-       /**
-        * Tests the current value against all registered validators.
-        * 
-        * @return <code>true</code> if all registered validators claim that the
-        *         current value is valid, <code>false</code> otherwise.
-        */
-       public boolean isValid() {
-
-               if (validators == null) {
-                       return true;
-               }
-
-               final Object value = getValue();
-               for (final Iterator i = validators.iterator(); i.hasNext();) {
-                       if (!((Validator) i.next()).isValid(value)) {
-                               return false;
-                       }
-               }
-
-               return true;
-       }
-
-       /**
-        * Checks the validity of the validatable
-        * 
-        * @see com.itmill.toolkit.data.Validatable#validate()
-        */
-       public void validate() throws Validator.InvalidValueException {
-
-               // If there is no validator, there can not be any errors
-               if (validators == null) {
-                       return;
-               }
-
-               // Initialize temps
-               Validator.InvalidValueException firstError = null;
-               LinkedList errors = null;
-               final Object value = getValue();
-
-               // Gets all the validation errors
-               for (final Iterator i = validators.iterator(); i.hasNext();) {
-                       try {
-                               ((Validator) i.next()).validate(value);
-                       } catch (final Validator.InvalidValueException e) {
-                               if (firstError == null) {
-                                       firstError = e;
-                               } else {
-                                       if (errors == null) {
-                                               errors = new LinkedList();
-                                               errors.add(firstError);
-                                       }
-                                       errors.add(e);
-                               }
-                       }
-               }
-
-               // If there were no error
-               if (firstError == null) {
-                       return;
-               }
-
-               // If only one error occurred, throw it forwards
-               if (errors == null) {
-                       throw firstError;
-               }
-
-               // Creates composite validator
-               final Validator.InvalidValueException[] exceptions = new Validator.InvalidValueException[errors
-                               .size()];
-               int index = 0;
-               for (final Iterator i = errors.iterator(); i.hasNext();) {
-                       exceptions[index++] = (Validator.InvalidValueException) i.next();
-               }
-
-               throw new Validator.InvalidValueException(null, exceptions);
-       }
-
-       /**
-        * Fields allow invalid values by default. In most cases this is wanted,
-        * because the field otherwise visually forget the user input immediately.
-        * 
-        * @return true iff the invalid values are allowed.
-        * @see com.itmill.toolkit.data.Validatable#isInvalidAllowed()
-        */
-       public boolean isInvalidAllowed() {
-               return invalidAllowed;
-       }
-
-       /**
-        * Fields allow invalid values by default. In most cases this is wanted,
-        * because the field otherwise visually forget the user input immediately.
-        * <p>
-        * In common setting where the user wants to assure the correctness of the
-        * datasource, but allow temporarily invalid contents in the field, the user
-        * should add the validators to datasource, that should not allow invalid
-        * values. The validators are automatically copied to the field when the
-        * datasource is set.
-        * </p>
-        * 
-        * @see com.itmill.toolkit.data.Validatable#setInvalidAllowed(boolean)
-        */
-       public void setInvalidAllowed(boolean invalidAllowed)
-                       throws UnsupportedOperationException {
-               this.invalidAllowed = invalidAllowed;
-       }
-
-       /**
-        * Error messages shown by the fields are composites of the error message
-        * thrown by the superclasses (that is the component error message),
-        * validation errors and buffered source errors.
-        * 
-        * @see com.itmill.toolkit.ui.AbstractComponent#getErrorMessage()
-        */
-       public ErrorMessage getErrorMessage() {
-
-               // Check validation errors
-               ErrorMessage validationError = null;
-               try {
-                       validate();
-               } catch (Validator.InvalidValueException e) {
-                       validationError = e;
-               }
-
-               // Check if there are any systems errors
-               final ErrorMessage superError = super.getErrorMessage();
-
-               // Return if there are no errors at all
-               if (superError == null && validationError == null
-                               && currentBufferedSourceException == null)
-                       return null;
-
-               // Throw combination of the error types
-               return new CompositeErrorMessage(new ErrorMessage[] { superError,
-                               validationError, currentBufferedSourceException });
-
-       }
-
-       /* Value change events ****************************************** */
-
-       private static final Method VALUE_CHANGE_METHOD;
-
-       static {
-               try {
-                       VALUE_CHANGE_METHOD = Property.ValueChangeListener.class
-                                       .getDeclaredMethod("valueChange",
-                                                       new Class[] { Property.ValueChangeEvent.class });
-               } catch (final java.lang.NoSuchMethodException e) {
-                       // This should never happen
-                       throw new java.lang.RuntimeException();
-               }
-       }
-
-       /*
-        * Adds a value change listener for the field. Don't add a JavaDoc comment
-        * here, we use the default documentation from the implemented interface.
-        */
-       public void addListener(Property.ValueChangeListener listener) {
-               addListener(AbstractField.ValueChangeEvent.class, listener,
-                               VALUE_CHANGE_METHOD);
-       }
-
-       /*
-        * Removes a value change listener from the field. Don't add a JavaDoc
-        * comment here, we use the default documentation from the implemented
-        * interface.
-        */
-       public void removeListener(Property.ValueChangeListener listener) {
-               removeListener(AbstractField.ValueChangeEvent.class, listener,
-                               VALUE_CHANGE_METHOD);
-       }
-
-       /**
-        * Emits the value change event. The value contained in the field is
-        * validated before the event is created.
-        */
-       protected void fireValueChange(boolean repaintIsNotNeeded) {
-               fireEvent(new AbstractField.ValueChangeEvent(this));
-               if (!repaintIsNotNeeded) {
-                       requestRepaint();
-               }
-       }
-
-       /* Read-only status change events *************************************** */
-
-       private static final Method READ_ONLY_STATUS_CHANGE_METHOD;
-
-       static {
-               try {
-                       READ_ONLY_STATUS_CHANGE_METHOD = Property.ReadOnlyStatusChangeListener.class
-                                       .getDeclaredMethod(
-                                                       "readOnlyStatusChange",
-                                                       new Class[] { Property.ReadOnlyStatusChangeEvent.class });
-               } catch (final java.lang.NoSuchMethodException e) {
-                       // This should never happen
-                       throw new java.lang.RuntimeException();
-               }
-       }
-
-       /**
-        * An <code>Event</code> object specifying the Property whose read-only
-        * status has changed.
-        * 
-        * @author IT Mill Ltd.
-        * @version
-        * @VERSION@
-        * @since 3.0
-        */
-       public class ReadOnlyStatusChangeEvent extends Component.Event implements
-                       Property.ReadOnlyStatusChangeEvent {
-
-               /**
-                * Serial generated by eclipse.
-                */
-               private static final long serialVersionUID = 3258688823264161846L;
-
-               /**
-                * New instance of text change event.
-                * 
-                * @param source
-                *            the Source of the event.
-                */
-               public ReadOnlyStatusChangeEvent(AbstractField source) {
-                       super(source);
-               }
-
-               /**
-                * Property where the event occurred.
-                * 
-                * @return the Source of the event.
-                */
-               public Property getProperty() {
-                       return (Property) getSource();
-               }
-       }
-
-       /*
-        * Adds a read-only status change listener for the field. Don't add a
-        * JavaDoc comment here, we use the default documentation from the
-        * implemented interface.
-        */
-       public void addListener(Property.ReadOnlyStatusChangeListener listener) {
-               addListener(Property.ReadOnlyStatusChangeEvent.class, listener,
-                               READ_ONLY_STATUS_CHANGE_METHOD);
-       }
-
-       /*
-        * Removes a read-only status change listener from the field. Don't add a
-        * JavaDoc comment here, we use the default documentation from the
-        * implemented interface.
-        */
-       public void removeListener(Property.ReadOnlyStatusChangeListener listener) {
-               removeListener(Property.ReadOnlyStatusChangeEvent.class, listener,
-                               READ_ONLY_STATUS_CHANGE_METHOD);
-       }
-
-       /**
-        * Emits the read-only status change event. The value contained in the field
-        * is validated before the event is created.
-        */
-       protected void fireReadOnlyStatusChange() {
-               fireEvent(new AbstractField.ReadOnlyStatusChangeEvent(this));
-       }
-
-       /**
-        * This method listens to data source value changes and passes the changes
-        * forwards.
-        * 
-        * @param event
-        *            the value change event telling the data source contents have
-        *            changed.
-        */
-       public void valueChange(Property.ValueChangeEvent event) {
-               if (isReadThrough() || !isModified()) {
-                       fireValueChange(false);
-               }
-       }
-
-       public void changeVariables(Object source, Map variables) {
-               super.changeVariables(source, variables);
-               if (validators != null && !validators.isEmpty()) requestRepaint();
-       }
-
-       /**
-        * Asks the terminal to place the cursor to this field.
-        */
-       public void focus() {
-               final Application app = getApplication();
-               if (app != null) {
-                       app.setFocusedComponent(this);
-               } else {
-                       delayedFocus = true;
-               }
-       }
-
-       /**
-        * Creates abstract field by the type of the property.
-        * 
-        * <p>
-        * This returns most suitable field type for editing property of given type.
-        * </p>
-        * 
-        * @param propertyType
-        *            the Type of the property, that needs to be edited.
-        */
-       public static AbstractField constructField(Class propertyType) {
-
-               // Null typed properties can not be edited
-               if (propertyType == null) {
-                       return null;
-               }
-
-               // Date field
-               if (Date.class.isAssignableFrom(propertyType)) {
-                       return new DateField();
-               }
-
-               // Boolean field
-               if (Boolean.class.isAssignableFrom(propertyType)) {
-                       final Button button = new Button("");
-                       button.setSwitchMode(true);
-                       button.setImmediate(false);
-                       return button;
-               }
-
-               // Text field is used by default
-               return new TextField();
-       }
-
-       /**
-        * Gets the tab index of this field. The tab index property is used to
-        * specify the natural tab ordering of fields.
-        * 
-        * @return the Tab index of this field. Negative value means unspecified.
-        */
-       public int getTabIndex() {
-               return tabIndex;
-       }
-
-       /**
-        * Gets the tab index of this field. The tab index property is used to
-        * specify the natural tab ordering of fields.
-        * 
-        * @param tabIndex
-        *            the tab order of this component. Negative value means
-        *            unspecified.
-        */
-       public void setTabIndex(int tabIndex) {
-               this.tabIndex = tabIndex;
-       }
-
-       /**
-        * Sets the internal field value. This is purely used by AbstractField to
-        * change the internal Field value. It does not trigger any events. It can
-        * be overriden by the inheriting classes to update all dependent variables.
-        * 
-        * @param newValue
-        *            the new value to be set.
-        */
-       protected void setInternalValue(Object newValue) {
-               value = newValue;
-       }
-
-       /**
-        * Notifies the component that it is connected to an application.
-        * 
-        * @see com.itmill.toolkit.ui.Component#attach()
-        */
-       public void attach() {
-               super.attach();
-               if (delayedFocus) {
-                       delayedFocus = false;
-                       focus();
-               }
-       }
-
-       /**
-        * Is this field required. Required fields must filled by the user.
-        * 
-        * @return <code>true</code> if the field is required .otherwise
-        *         <code>false</code>.
-        */
-       public boolean isRequired() {
-               return required;
-       }
-
-       /**
-        * Sets the field required. Required fields must filled by the user.
-        * 
-        * @param required
-        *            Is the field required.
-        */
-       public void setRequired(boolean required) {
-               this.required = required;
-               requestRepaint();
-       }
+        Property.ReadOnlyStatusChangeNotifier {
+
+    /* Private members ************************************************* */
+
+    private boolean delayedFocus;
+
+    /**
+     * Value of the datafield.
+     */
+    private Object value;
+
+    /**
+     * Connected data-source.
+     */
+    private Property dataSource = null;
+
+    /**
+     * The list of validators.
+     */
+    private LinkedList validators = null;
+
+    /**
+     * Auto commit mode.
+     */
+    private boolean writeTroughMode = true;
+
+    /**
+     * Reads the value from data-source, when it is not modified.
+     */
+    private boolean readTroughMode = true;
+
+    /**
+     * Is the field modified but not committed.
+     */
+    private boolean modified = false;
+
+    /**
+     * Current source exception.
+     */
+    private Buffered.SourceException currentBufferedSourceException = null;
+
+    /**
+     * Are the invalid values allowed in fields ?
+     */
+    private boolean invalidAllowed = true;
+
+    /**
+     * Are the invalid values committed ?
+     */
+    private boolean invalidCommitted = false;
+
+    /**
+     * The tab order number of this field.
+     */
+    private int tabIndex = 0;
+
+    /**
+     * Required field.
+     */
+    private boolean required = false;
+
+    /* Component basics ************************************************ */
+
+    /*
+     * Paints the field. Don't add a JavaDoc comment here, we use the default
+     * documentation from the implemented interface.
+     */
+    public void paintContent(PaintTarget target) throws PaintException {
+
+        // The tab ordering number
+        if (tabIndex > 0) {
+            target.addAttribute("tabindex", tabIndex);
+        }
+
+        // If the field is modified, but not committed, set modified attribute
+        if (isModified()) {
+            target.addAttribute("modified", true);
+        }
+
+        // Adds the required attribute
+        if (isRequired()) {
+            target.addAttribute("required", true);
+        }
+    }
+
+    /*
+     * Gets the field type Don't add a JavaDoc comment here, we use the default
+     * documentation from the implemented interface.
+     */
+    public abstract Class getType();
+
+    /**
+     * The abstract field is read only also if the data source is in read only
+     * mode.
+     */
+    public boolean isReadOnly() {
+        return super.isReadOnly()
+                || (dataSource != null && dataSource.isReadOnly());
+    }
+
+    /**
+     * Changes the readonly state and throw read-only status change events.
+     * 
+     * @see com.itmill.toolkit.ui.Component#setReadOnly(boolean)
+     */
+    public void setReadOnly(boolean readOnly) {
+        super.setReadOnly(readOnly);
+        fireReadOnlyStatusChange();
+    }
+
+    /**
+     * Tests if the invalid data is committed to datasource.
+     * 
+     * @see com.itmill.toolkit.data.BufferedValidatable#isInvalidCommitted()
+     */
+    public boolean isInvalidCommitted() {
+        return invalidCommitted;
+    }
+
+    /**
+     * Sets if the invalid data should be committed to datasource.
+     * 
+     * @see com.itmill.toolkit.data.BufferedValidatable#setInvalidCommitted(boolean)
+     */
+    public void setInvalidCommitted(boolean isCommitted) {
+        invalidCommitted = isCommitted;
+    }
+
+    /*
+     * Saves the current value to the data source Don't add a JavaDoc comment
+     * here, we use the default documentation from the implemented interface.
+     */
+    public void commit() throws Buffered.SourceException {
+        if (dataSource != null && (isInvalidCommitted() || isValid())
+                && !dataSource.isReadOnly()) {
+            final Object newValue = getValue();
+            try {
+
+                // Commits the value to datasource.
+                dataSource.setValue(newValue);
+
+            } catch (final Throwable e) {
+
+                // Sets the buffering state.
+                currentBufferedSourceException = new Buffered.SourceException(
+                        this, e);
+                requestRepaint();
+
+                // Throws the source exception.
+                throw currentBufferedSourceException;
+            }
+        }
+
+        boolean repaintNeeded = false;
+
+        // The abstract field is not modified anymore
+        if (modified) {
+            modified = false;
+            repaintNeeded = true;
+        }
+
+        // If successful, remove set the buffering state to be ok
+        if (currentBufferedSourceException != null) {
+            currentBufferedSourceException = null;
+            repaintNeeded = true;
+        }
+
+        if (repaintNeeded) {
+            requestRepaint();
+        }
+    }
+
+    /*
+     * Updates the value from the data source. Don't add a JavaDoc comment here,
+     * we use the default documentation from the implemented interface.
+     */
+    public void discard() throws Buffered.SourceException {
+        if (dataSource != null) {
+
+            // Gets the correct value from datasource
+            Object newValue;
+            try {
+
+                // Discards buffer by overwriting from datasource
+                newValue = dataSource.getValue();
+
+                // If successful, remove set the buffering state to be ok
+                if (currentBufferedSourceException != null) {
+                    currentBufferedSourceException = null;
+                    requestRepaint();
+                }
+            } catch (final Throwable e) {
+
+                // Sets the buffering state
+                currentBufferedSourceException = new Buffered.SourceException(
+                        this, e);
+                requestRepaint();
+
+                // Throws the source exception
+                throw currentBufferedSourceException;
+            }
+
+            final boolean wasModified = isModified();
+            modified = false;
+
+            // If the new value differs from the previous one
+            if ((newValue == null && value != null)
+                    || (newValue != null && !newValue.equals(value))) {
+                setInternalValue(newValue);
+                fireValueChange(false);
+            }
+
+            // If the value did not change, but the modification status did
+            else if (wasModified) {
+                requestRepaint();
+            }
+        }
+    }
+
+    /*
+     * Has the field been modified since the last commit()? Don't add a JavaDoc
+     * comment here, we use the default documentation from the implemented
+     * interface.
+     */
+    public boolean isModified() {
+        return modified;
+    }
+
+    /*
+     * Tests if the field is in write-through mode. Don't add a JavaDoc comment
+     * here, we use the default documentation from the implemented interface.
+     */
+    public boolean isWriteThrough() {
+        return writeTroughMode;
+    }
+
+    /*
+     * Sets the field's write-through mode to the specified status Don't add a
+     * JavaDoc comment here, we use the default documentation from the
+     * implemented interface.
+     */
+    public void setWriteThrough(boolean writeTrough)
+            throws Buffered.SourceException {
+        if (writeTroughMode == writeTrough) {
+            return;
+        }
+        writeTroughMode = writeTrough;
+        if (writeTroughMode) {
+            commit();
+        }
+    }
+
+    /*
+     * Tests if the field is in read-through mode. Don't add a JavaDoc comment
+     * here, we use the default documentation from the implemented interface.
+     */
+    public boolean isReadThrough() {
+        return readTroughMode;
+    }
+
+    /*
+     * Sets the field's read-through mode to the specified status Don't add a
+     * JavaDoc comment here, we use the default documentation from the
+     * implemented interface.
+     */
+    public void setReadThrough(boolean readTrough)
+            throws Buffered.SourceException {
+        if (readTroughMode == readTrough) {
+            return;
+        }
+        readTroughMode = readTrough;
+        if (!isModified() && readTroughMode && dataSource != null) {
+            setInternalValue(dataSource.getValue());
+            fireValueChange(false);
+        }
+    }
+
+    /* Property interface implementation ******************************* */
+
+    /**
+     * Returns the value of the Property in human readable textual format.
+     * 
+     * @see java.lang.Object#toString()
+     */
+    public String toString() {
+        final Object value = getValue();
+        if (value == null) {
+            return null;
+        }
+        return getValue().toString();
+    }
+
+    /**
+     * Gets the current value of the field. This is the visible, modified and
+     * possible invalid value the user have entered to the field. In the
+     * read-through mode, the abstract buffer is also updated and validation is
+     * performed.
+     * 
+     * @return the current value of the field.
+     */
+    public Object getValue() {
+
+        // Give the value from abstract buffers if the field if possible
+        if (dataSource == null || !isReadThrough() || isModified()) {
+            return value;
+        }
+
+        final Object newValue = dataSource.getValue();
+        if ((newValue == null && value != null)
+                || (newValue != null && !newValue.equals(value))) {
+            setInternalValue(newValue);
+            fireValueChange(false);
+        }
+
+        return newValue;
+    }
+
+    /**
+     * Sets the value of the field.
+     * 
+     * @param newValue
+     *                the New value of the field.
+     * @throws Property.ReadOnlyException
+     * @throws Property.ConversionException
+     */
+    public void setValue(Object newValue) throws Property.ReadOnlyException,
+            Property.ConversionException {
+        setValue(newValue, false);
+    }
+
+    /**
+     * Sets the value of the field.
+     * 
+     * @param newValue
+     *                the New value of the field.
+     * @param repaintIsNotNeeded
+     *                True iff caller is sure that repaint is not needed.
+     * @throws Property.ReadOnlyException
+     * @throws Property.ConversionException
+     */
+    protected void setValue(Object newValue, boolean repaintIsNotNeeded)
+            throws Property.ReadOnlyException, Property.ConversionException {
+
+        if ((newValue == null && value != null)
+                || (newValue != null && !newValue.equals(value))) {
+
+            // Read only fields can not be changed
+            if (isReadOnly()) {
+                throw new Property.ReadOnlyException();
+            }
+
+            // If invalid values are not allowed, the value must be checked
+            if (!isInvalidAllowed()) {
+                final Collection v = getValidators();
+                if (v != null) {
+                    for (final Iterator i = v.iterator(); i.hasNext();) {
+                        ((Validator) i.next()).validate(newValue);
+                    }
+                }
+            }
+
+            // Changes the value
+            setInternalValue(newValue);
+            modified = dataSource != null;
+
+            // In write trough mode , try to commit
+            if (isWriteThrough() && dataSource != null
+                    && (isInvalidCommitted() || isValid())) {
+                try {
+
+                    // Commits the value to datasource
+                    dataSource.setValue(newValue);
+
+                    // The buffer is now unmodified
+                    modified = false;
+
+                } catch (final Throwable e) {
+
+                    // Sets the buffering state
+                    currentBufferedSourceException = new Buffered.SourceException(
+                            this, e);
+                    requestRepaint();
+
+                    // Throws the source exception
+                    throw currentBufferedSourceException;
+                }
+            }
+
+            // If successful, remove set the buffering state to be ok
+            if (currentBufferedSourceException != null) {
+                currentBufferedSourceException = null;
+                requestRepaint();
+            }
+
+            // Fires the value change
+            fireValueChange(repaintIsNotNeeded);
+        }
+    }
+
+    /* External data source ******************************************** */
+
+    /**
+     * Gets the current data source of the field, if any.
+     * 
+     * @return the current data source as a Property, or <code>null</code> if
+     *         none defined.
+     */
+    public Property getPropertyDataSource() {
+        return dataSource;
+    }
+
+    /**
+     * <p>
+     * Sets the specified Property as the data source for the field. All
+     * uncommitted changes to the field are discarded and the value is refreshed
+     * from the new data source.
+     * </p>
+     * 
+     * <p>
+     * If the datasource has any validators, the same validators are added to
+     * the field. Because the default behavior of the field is to allow invalid
+     * values, but not to allow committing them, this only adds visual error
+     * messages to fields and do not allow committing them as long as the value
+     * is invalid. After the value is valid, the error message is not shown and
+     * the commit can be done normally.
+     * </p>
+     * 
+     * @param newDataSource
+     *                the new data source Property.
+     */
+    public void setPropertyDataSource(Property newDataSource) {
+
+        // Saves the old value
+        final Object oldValue = value;
+
+        // Discards all changes to old datasource
+        try {
+            discard();
+        } catch (final Buffered.SourceException ignored) {
+        }
+
+        // Stops listening the old data source changes
+        if (dataSource != null
+                && Property.ValueChangeNotifier.class
+                        .isAssignableFrom(dataSource.getClass())) {
+            ((Property.ValueChangeNotifier) dataSource).removeListener(this);
+        }
+
+        // Sets the new data source
+        dataSource = newDataSource;
+
+        // Gets the value from source
+        try {
+            if (dataSource != null) {
+                setInternalValue(dataSource.getValue());
+            }
+            modified = false;
+        } catch (final Throwable e) {
+            currentBufferedSourceException = new Buffered.SourceException(this,
+                    e);
+            modified = true;
+        }
+
+        // Listens the new data source if possible
+        if (dataSource instanceof Property.ValueChangeNotifier) {
+            ((Property.ValueChangeNotifier) dataSource).addListener(this);
+        }
+
+        // Copy the validators from the data source
+        if (dataSource instanceof Validatable) {
+            final Collection validators = ((Validatable) dataSource)
+                    .getValidators();
+            if (validators != null) {
+                for (final Iterator i = validators.iterator(); i.hasNext();) {
+                    addValidator((Validator) i.next());
+                }
+            }
+        }
+
+        // Fires value change if the value has changed
+        if ((value != oldValue)
+                && ((value != null && !value.equals(oldValue)) || value == null)) {
+            fireValueChange(false);
+        }
+    }
+
+    /* Validation ****************************************************** */
+
+    /**
+     * Adds a new validator for the field's value. All validators added to a
+     * field are checked each time the its value changes.
+     * 
+     * @param validator
+     *                the new validator to be added.
+     */
+    public void addValidator(Validator validator) {
+        if (validators == null) {
+            validators = new LinkedList();
+        }
+        validators.add(validator);
+    }
+
+    /**
+     * Gets the validators of the field.
+     * 
+     * @return the Unmodifiable collection that holds all validators for the
+     *         field.
+     */
+    public Collection getValidators() {
+        if (validators == null || validators.isEmpty()) {
+            return null;
+        }
+        return Collections.unmodifiableCollection(validators);
+    }
+
+    /**
+     * Removes the validator from the field.
+     * 
+     * @param validator
+     *                the validator to remove.
+     */
+    public void removeValidator(Validator validator) {
+        if (validators != null) {
+            validators.remove(validator);
+        }
+    }
+
+    /**
+     * Tests the current value against all registered validators.
+     * 
+     * @return <code>true</code> if all registered validators claim that the
+     *         current value is valid, <code>false</code> otherwise.
+     */
+    public boolean isValid() {
+
+        if (validators == null) {
+            return true;
+        }
+
+        final Object value = getValue();
+        for (final Iterator i = validators.iterator(); i.hasNext();) {
+            if (!((Validator) i.next()).isValid(value)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Checks the validity of the validatable
+     * 
+     * @see com.itmill.toolkit.data.Validatable#validate()
+     */
+    public void validate() throws Validator.InvalidValueException {
+
+        // If there is no validator, there can not be any errors
+        if (validators == null) {
+            return;
+        }
+
+        // Initialize temps
+        Validator.InvalidValueException firstError = null;
+        LinkedList errors = null;
+        final Object value = getValue();
+
+        // Gets all the validation errors
+        for (final Iterator i = validators.iterator(); i.hasNext();) {
+            try {
+                ((Validator) i.next()).validate(value);
+            } catch (final Validator.InvalidValueException e) {
+                if (firstError == null) {
+                    firstError = e;
+                } else {
+                    if (errors == null) {
+                        errors = new LinkedList();
+                        errors.add(firstError);
+                    }
+                    errors.add(e);
+                }
+            }
+        }
+
+        // If there were no error
+        if (firstError == null) {
+            return;
+        }
+
+        // If only one error occurred, throw it forwards
+        if (errors == null) {
+            throw firstError;
+        }
+
+        // Creates composite validator
+        final Validator.InvalidValueException[] exceptions = new Validator.InvalidValueException[errors
+                .size()];
+        int index = 0;
+        for (final Iterator i = errors.iterator(); i.hasNext();) {
+            exceptions[index++] = (Validator.InvalidValueException) i.next();
+        }
+
+        throw new Validator.InvalidValueException(null, exceptions);
+    }
+
+    /**
+     * Fields allow invalid values by default. In most cases this is wanted,
+     * because the field otherwise visually forget the user input immediately.
+     * 
+     * @return true iff the invalid values are allowed.
+     * @see com.itmill.toolkit.data.Validatable#isInvalidAllowed()
+     */
+    public boolean isInvalidAllowed() {
+        return invalidAllowed;
+    }
+
+    /**
+     * Fields allow invalid values by default. In most cases this is wanted,
+     * because the field otherwise visually forget the user input immediately.
+     * <p>
+     * In common setting where the user wants to assure the correctness of the
+     * datasource, but allow temporarily invalid contents in the field, the user
+     * should add the validators to datasource, that should not allow invalid
+     * values. The validators are automatically copied to the field when the
+     * datasource is set.
+     * </p>
+     * 
+     * @see com.itmill.toolkit.data.Validatable#setInvalidAllowed(boolean)
+     */
+    public void setInvalidAllowed(boolean invalidAllowed)
+            throws UnsupportedOperationException {
+        this.invalidAllowed = invalidAllowed;
+    }
+
+    /**
+     * Error messages shown by the fields are composites of the error message
+     * thrown by the superclasses (that is the component error message),
+     * validation errors and buffered source errors.
+     * 
+     * @see com.itmill.toolkit.ui.AbstractComponent#getErrorMessage()
+     */
+    public ErrorMessage getErrorMessage() {
+
+        // Check validation errors
+        ErrorMessage validationError = null;
+        try {
+            validate();
+        } catch (Validator.InvalidValueException e) {
+            validationError = e;
+        }
+
+        // Check if there are any systems errors
+        final ErrorMessage superError = super.getErrorMessage();
+
+        // Return if there are no errors at all
+        if (superError == null && validationError == null
+                && currentBufferedSourceException == null) {
+            return null;
+        }
+
+        // Throw combination of the error types
+        return new CompositeErrorMessage(new ErrorMessage[] { superError,
+                validationError, currentBufferedSourceException });
+
+    }
+
+    /* Value change events ****************************************** */
+
+    private static final Method VALUE_CHANGE_METHOD;
+
+    static {
+        try {
+            VALUE_CHANGE_METHOD = Property.ValueChangeListener.class
+                    .getDeclaredMethod("valueChange",
+                            new Class[] { Property.ValueChangeEvent.class });
+        } catch (final java.lang.NoSuchMethodException e) {
+            // This should never happen
+            throw new java.lang.RuntimeException();
+        }
+    }
+
+    /*
+     * Adds a value change listener for the field. Don't add a JavaDoc comment
+     * here, we use the default documentation from the implemented interface.
+     */
+    public void addListener(Property.ValueChangeListener listener) {
+        addListener(AbstractField.ValueChangeEvent.class, listener,
+                VALUE_CHANGE_METHOD);
+    }
+
+    /*
+     * Removes a value change listener from the field. Don't add a JavaDoc
+     * comment here, we use the default documentation from the implemented
+     * interface.
+     */
+    public void removeListener(Property.ValueChangeListener listener) {
+        removeListener(AbstractField.ValueChangeEvent.class, listener,
+                VALUE_CHANGE_METHOD);
+    }
+
+    /**
+     * Emits the value change event. The value contained in the field is
+     * validated before the event is created.
+     */
+    protected void fireValueChange(boolean repaintIsNotNeeded) {
+        fireEvent(new AbstractField.ValueChangeEvent(this));
+        if (!repaintIsNotNeeded) {
+            requestRepaint();
+        }
+    }
+
+    /* Read-only status change events *************************************** */
+
+    private static final Method READ_ONLY_STATUS_CHANGE_METHOD;
+
+    static {
+        try {
+            READ_ONLY_STATUS_CHANGE_METHOD = Property.ReadOnlyStatusChangeListener.class
+                    .getDeclaredMethod(
+                            "readOnlyStatusChange",
+                            new Class[] { Property.ReadOnlyStatusChangeEvent.class });
+        } catch (final java.lang.NoSuchMethodException e) {
+            // This should never happen
+            throw new java.lang.RuntimeException();
+        }
+    }
+
+    /**
+     * An <code>Event</code> object specifying the Property whose read-only
+     * status has changed.
+     * 
+     * @author IT Mill Ltd.
+     * @version
+     * @VERSION@
+     * @since 3.0
+     */
+    public class ReadOnlyStatusChangeEvent extends Component.Event implements
+            Property.ReadOnlyStatusChangeEvent {
+
+        /**
+         * Serial generated by eclipse.
+         */
+        private static final long serialVersionUID = 3258688823264161846L;
+
+        /**
+         * New instance of text change event.
+         * 
+         * @param source
+         *                the Source of the event.
+         */
+        public ReadOnlyStatusChangeEvent(AbstractField source) {
+            super(source);
+        }
+
+        /**
+         * Property where the event occurred.
+         * 
+         * @return the Source of the event.
+         */
+        public Property getProperty() {
+            return (Property) getSource();
+        }
+    }
+
+    /*
+     * Adds a read-only status change listener for the field. Don't add a
+     * JavaDoc comment here, we use the default documentation from the
+     * implemented interface.
+     */
+    public void addListener(Property.ReadOnlyStatusChangeListener listener) {
+        addListener(Property.ReadOnlyStatusChangeEvent.class, listener,
+                READ_ONLY_STATUS_CHANGE_METHOD);
+    }
+
+    /*
+     * Removes a read-only status change listener from the field. Don't add a
+     * JavaDoc comment here, we use the default documentation from the
+     * implemented interface.
+     */
+    public void removeListener(Property.ReadOnlyStatusChangeListener listener) {
+        removeListener(Property.ReadOnlyStatusChangeEvent.class, listener,
+                READ_ONLY_STATUS_CHANGE_METHOD);
+    }
+
+    /**
+     * Emits the read-only status change event. The value contained in the field
+     * is validated before the event is created.
+     */
+    protected void fireReadOnlyStatusChange() {
+        fireEvent(new AbstractField.ReadOnlyStatusChangeEvent(this));
+    }
+
+    /**
+     * This method listens to data source value changes and passes the changes
+     * forwards.
+     * 
+     * @param event
+     *                the value change event telling the data source contents
+     *                have changed.
+     */
+    public void valueChange(Property.ValueChangeEvent event) {
+        if (isReadThrough() || !isModified()) {
+            fireValueChange(false);
+        }
+    }
+
+    public void changeVariables(Object source, Map variables) {
+        super.changeVariables(source, variables);
+        if (validators != null && !validators.isEmpty()) {
+            requestRepaint();
+        }
+    }
+
+    /**
+     * Asks the terminal to place the cursor to this field.
+     */
+    public void focus() {
+        final Application app = getApplication();
+        if (app != null) {
+            app.setFocusedComponent(this);
+        } else {
+            delayedFocus = true;
+        }
+    }
+
+    /**
+     * Creates abstract field by the type of the property.
+     * 
+     * <p>
+     * This returns most suitable field type for editing property of given type.
+     * </p>
+     * 
+     * @param propertyType
+     *                the Type of the property, that needs to be edited.
+     */
+    public static AbstractField constructField(Class propertyType) {
+
+        // Null typed properties can not be edited
+        if (propertyType == null) {
+            return null;
+        }
+
+        // Date field
+        if (Date.class.isAssignableFrom(propertyType)) {
+            return new DateField();
+        }
+
+        // Boolean field
+        if (Boolean.class.isAssignableFrom(propertyType)) {
+            final Button button = new Button("");
+            button.setSwitchMode(true);
+            button.setImmediate(false);
+            return button;
+        }
+
+        // Text field is used by default
+        return new TextField();
+    }
+
+    /**
+     * Gets the tab index of this field. The tab index property is used to
+     * specify the natural tab ordering of fields.
+     * 
+     * @return the Tab index of this field. Negative value means unspecified.
+     */
+    public int getTabIndex() {
+        return tabIndex;
+    }
+
+    /**
+     * Gets the tab index of this field. The tab index property is used to
+     * specify the natural tab ordering of fields.
+     * 
+     * @param tabIndex
+     *                the tab order of this component. Negative value means
+     *                unspecified.
+     */
+    public void setTabIndex(int tabIndex) {
+        this.tabIndex = tabIndex;
+    }
+
+    /**
+     * Sets the internal field value. This is purely used by AbstractField to
+     * change the internal Field value. It does not trigger any events. It can
+     * be overriden by the inheriting classes to update all dependent variables.
+     * 
+     * @param newValue
+     *                the new value to be set.
+     */
+    protected void setInternalValue(Object newValue) {
+        value = newValue;
+    }
+
+    /**
+     * Notifies the component that it is connected to an application.
+     * 
+     * @see com.itmill.toolkit.ui.Component#attach()
+     */
+    public void attach() {
+        super.attach();
+        if (delayedFocus) {
+
+            delayedFocus = false;
+            focus();
+        }
+    }
+
+    /**
+     * Is this field required. Required fields must filled by the user.
+     * 
+     * @return <code>true</code> if the field is required .otherwise
+     *         <code>false</code>.
+     */
+    public boolean isRequired() {
+        return required;
+    }
+
+    /**
+     * Sets the field required. Required fields must filled by the user.
+     * 
+     * @param required
+     *                Is the field required.
+     */
+    public void setRequired(boolean required) {
+        this.required = required;
+        requestRepaint();
+    }
 
 }
\ No newline at end of file