]> source.dussan.org Git - vaadin-framework.git/commitdiff
Update value when field/label local changes (#8192) 26/326/3
authorArtur Signell <artur@vaadin.com>
Wed, 21 Nov 2012 15:13:10 +0000 (17:13 +0200)
committerVaadin Code Review <review@vaadin.com>
Thu, 22 Nov 2012 15:03:20 +0000 (15:03 +0000)
Change-Id: Ifbb426f7aee107db0be555c5ab1ef0b5f4948e5e

server/src/com/vaadin/ui/AbstractField.java
server/src/com/vaadin/ui/Label.java
uitest/src/com/vaadin/tests/converter/ConverterThatEnforcesAFormat.java

index b52d733632221c7ed037a2d3d9976aa38d3130e4..59e986cd2328ee49a7a37a6e81e252dd0087aa7b 100644 (file)
@@ -24,6 +24,7 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Locale;
 import java.util.logging.Logger;
 
 import com.vaadin.data.Buffered;
@@ -150,6 +151,11 @@ public abstract class AbstractField<T> extends AbstractComponent implements
      */
     private boolean isListeningToPropertyEvents = false;
 
+    /**
+     * The locale used when setting the value.
+     */
+    private Locale valueLocale = null;
+
     /* Component basics */
 
     /*
@@ -309,7 +315,7 @@ public abstract class AbstractField<T> extends AbstractComponent implements
         }
 
         // There is no buffered value so use whatever the data model provides
-        return convertFromDataSource(getDataSourceValue());
+        return convertFromModel(getDataSourceValue());
     }
 
     /*
@@ -452,7 +458,7 @@ public abstract class AbstractField<T> extends AbstractComponent implements
                 throw new Property.ReadOnlyException();
             }
             try {
-                T doubleConvertedFieldValue = convertFromDataSource(convertToModel(newFieldValue));
+                T doubleConvertedFieldValue = convertFromModel(convertToModel(newFieldValue));
                 if (!equals(newFieldValue, doubleConvertedFieldValue)) {
                     newFieldValue = doubleConvertedFieldValue;
                     repaintIsNotNeeded = false;
@@ -530,7 +536,7 @@ public abstract class AbstractField<T> extends AbstractComponent implements
         }
     }
 
-    private static boolean equals(Object value1, Object value2) {
+    static boolean equals(Object value1, Object value2) {
         if (value1 == null) {
             return value2 == null;
         }
@@ -617,7 +623,7 @@ public abstract class AbstractField<T> extends AbstractComponent implements
         // Gets the value from source
         try {
             if (dataSource != null) {
-                T fieldValue = convertFromDataSource(getDataSourceValue());
+                T fieldValue = convertFromModel(getDataSourceValue());
                 setInternalValue(fieldValue);
             }
             setModified(false);
@@ -679,9 +685,24 @@ public abstract class AbstractField<T> extends AbstractComponent implements
      *             if there is no converter and the type is not compatible with
      *             the data source type.
      */
-    private T convertFromDataSource(Object newValue) {
+    private T convertFromModel(Object newValue) {
+        return convertFromModel(newValue, getLocale());
+    }
+
+    /**
+     * Convert the given value from the data source type to the UI type.
+     * 
+     * @param newValue
+     *            The data source value to convert.
+     * @return The converted value that is compatible with the UI type or the
+     *         original value if its type is compatible and no converter is set.
+     * @throws Converter.ConversionException
+     *             if there is no converter and the type is not compatible with
+     *             the data source type.
+     */
+    private T convertFromModel(Object newValue, Locale locale) {
         return ConverterUtil.convertFromModel(newValue, getType(),
-                getConverter(), getLocale());
+                getConverter(), locale);
     }
 
     /**
@@ -697,6 +718,24 @@ public abstract class AbstractField<T> extends AbstractComponent implements
      */
     private Object convertToModel(T fieldValue)
             throws Converter.ConversionException {
+        return convertToModel(fieldValue, getLocale());
+    }
+
+    /**
+     * Convert the given value from the UI type to the data source type.
+     * 
+     * @param fieldValue
+     *            The value to convert. Typically returned by
+     *            {@link #getFieldValue()}
+     * @param locale
+     *            The locale to use for the conversion
+     * @return The converted value that is compatible with the data source type.
+     * @throws Converter.ConversionException
+     *             if there is no converter and the type is not compatible with
+     *             the data source type.
+     */
+    private Object convertToModel(T fieldValue, Locale locale)
+            throws Converter.ConversionException {
         Class<?> modelType = null;
         Property pd = getPropertyDataSource();
         if (pd != null) {
@@ -706,7 +745,7 @@ public abstract class AbstractField<T> extends AbstractComponent implements
         }
         try {
             return ConverterUtil.convertToModel(fieldValue,
-                    (Class<Object>) modelType, getConverter(), getLocale());
+                    (Class<Object>) modelType, getConverter(), locale);
         } catch (ConversionException e) {
             throw new ConversionException(getConversionError(modelType), e);
         }
@@ -753,7 +792,7 @@ public abstract class AbstractField<T> extends AbstractComponent implements
      *            The value to set. Must be the same type as the data source.
      */
     public void setConvertedValue(Object value) {
-        setValue(convertFromDataSource(value));
+        setValue(convertFromModel(value));
     }
 
     /* Validation */
@@ -1212,7 +1251,7 @@ public abstract class AbstractField<T> extends AbstractComponent implements
     }
 
     private void readValueFromProperty(Property.ValueChangeEvent event) {
-        setInternalValue(convertFromDataSource(event.getProperty().getValue()));
+        setInternalValue(convertFromModel(event.getProperty().getValue()));
     }
 
     /**
@@ -1273,6 +1312,7 @@ public abstract class AbstractField<T> extends AbstractComponent implements
      */
     protected void setInternalValue(T newValue) {
         value = newValue;
+        valueLocale = getLocale();
         if (validators != null && !validators.isEmpty()) {
             markAsDirty();
         }
@@ -1287,6 +1327,7 @@ public abstract class AbstractField<T> extends AbstractComponent implements
     public void attach() {
         super.attach();
 
+        localeMightHaveChanged();
         if (!isListeningToPropertyEvents) {
             addPropertyListeners();
             if (!isModified() && !isBuffered()) {
@@ -1296,6 +1337,19 @@ public abstract class AbstractField<T> extends AbstractComponent implements
         }
     }
 
+    @Override
+    public void setLocale(Locale locale) {
+        super.setLocale(locale);
+        localeMightHaveChanged();
+    }
+
+    private void localeMightHaveChanged() {
+        if (!equals(valueLocale, getLocale())) {
+            Object modelValue = convertToModel(getValue(), valueLocale);
+            setValue(convertFromModel(modelValue));
+        }
+    }
+
     @Override
     public void detach() {
         super.detach();
@@ -1516,7 +1570,7 @@ public abstract class AbstractField<T> extends AbstractComponent implements
             try {
 
                 // Discards buffer by overwriting from datasource
-                newFieldValue = convertFromDataSource(getDataSourceValue());
+                newFieldValue = convertFromModel(getDataSourceValue());
 
                 // If successful, remove set the buffering state to be ok
                 if (getCurrentBufferedSourceException() != null) {
index db5bc2862db882e20ec7eb3bbdbb9b271a229c36..1cc18d33bcc438d0256d4b151cd153be4348cccf 100644 (file)
@@ -17,6 +17,7 @@
 package com.vaadin.ui;
 
 import java.lang.reflect.Method;
+import java.util.Locale;
 import java.util.logging.Logger;
 
 import com.vaadin.data.Property;
@@ -174,8 +175,8 @@ public class Label extends AbstractComponent implements Property<String>,
     }
 
     /**
-     * Returns the current value of the data source. Assumes there is a data
-     * source.
+     * Returns the current value of the data source converted using the current
+     * locale.
      * 
      * @return
      */
@@ -412,10 +413,34 @@ public class Label extends AbstractComponent implements Property<String>,
      */
     @Override
     public void valueChange(Property.ValueChangeEvent event) {
+        updateValueFromDataSource();
+    }
+
+    private void updateValueFromDataSource() {
         // Update the internal value from the data source
-        getState().text = getValue();
+        String newConvertedValue = getDataSourceValue();
+        if (!AbstractField.equals(newConvertedValue, getState().text)) {
+            getState().text = newConvertedValue;
+            fireValueChange();
+        }
+    }
 
-        fireValueChange();
+    @Override
+    public void attach() {
+        super.attach();
+        localeMightHaveChanged();
+    }
+
+    @Override
+    public void setLocale(Locale locale) {
+        super.setLocale(locale);
+        localeMightHaveChanged();
+    }
+
+    private void localeMightHaveChanged() {
+        if (getPropertyDataSource() != null) {
+            updateValueFromDataSource();
+        }
     }
 
     private String getComparableValue() {
index 59aa45dc36841d64519406ef5e383961438c154f..6158092591a667511a6620d200ecacdaa786cb5b 100644 (file)
@@ -1,5 +1,7 @@
 package com.vaadin.tests.converter;
 
+import java.util.Locale;
+
 import com.vaadin.data.Property.ValueChangeEvent;
 import com.vaadin.data.Property.ValueChangeListener;
 import com.vaadin.tests.components.TestBase;
@@ -14,8 +16,9 @@ public class ConverterThatEnforcesAFormat extends TestBase {
     protected void setup() {
         final TextField tf = new TextField(
                 "This field should always be formatted with 3 digits");
+        tf.setLocale(Locale.ENGLISH);
         tf.setConverter(new StringToDoubleConverterWithThreeFractionDigits());
-        tf.addListener(new ValueChangeListener() {
+        tf.addValueChangeListener(new ValueChangeListener() {
             @Override
             public void valueChange(ValueChangeEvent event) {
                 log.log("Value changed to "