Browse Source

Merge remote branch 'origin/databinding'

Conflicts:
	src/com/vaadin/Application.java
	src/com/vaadin/ui/AbstractField.java
	tests/testbench/com/vaadin/tests/integration/LiferayThemeDemo.java
	tests/testbench/com/vaadin/tests/tickets/Ticket1673.java
tags/7.0.0.alpha1
Leif Åstrand 12 years ago
parent
commit
93155d8283
100 changed files with 2152 additions and 681 deletions
  1. 47
    0
      src/com/vaadin/Application.java
  2. 1
    1
      src/com/vaadin/data/Container.java
  3. 1
    1
      src/com/vaadin/data/Item.java
  4. 11
    23
      src/com/vaadin/data/Property.java
  5. 7
    12
      src/com/vaadin/data/Validator.java
  6. 44
    9
      src/com/vaadin/data/util/AbstractBeanContainer.java
  7. 22
    7
      src/com/vaadin/data/util/AbstractProperty.java
  8. 35
    1
      src/com/vaadin/data/util/BeanItem.java
  9. 1
    1
      src/com/vaadin/data/util/ContainerHierarchicalWrapper.java
  10. 1
    1
      src/com/vaadin/data/util/ContainerOrderedWrapper.java
  11. 2
    2
      src/com/vaadin/data/util/DefaultItemSorter.java
  12. 2
    2
      src/com/vaadin/data/util/FilesystemContainer.java
  13. 25
    10
      src/com/vaadin/data/util/IndexedContainer.java
  14. 13
    12
      src/com/vaadin/data/util/MethodProperty.java
  15. 1
    1
      src/com/vaadin/data/util/MethodPropertyDescriptor.java
  16. 7
    6
      src/com/vaadin/data/util/NestedMethodProperty.java
  17. 4
    3
      src/com/vaadin/data/util/NestedPropertyDescriptor.java
  18. 6
    7
      src/com/vaadin/data/util/ObjectProperty.java
  19. 21
    19
      src/com/vaadin/data/util/PropertyFormatter.java
  20. 5
    5
      src/com/vaadin/data/util/PropertysetItem.java
  21. 4
    3
      src/com/vaadin/data/util/QueryContainer.java
  22. 3
    3
      src/com/vaadin/data/util/TextFileProperty.java
  23. 1
    1
      src/com/vaadin/data/util/VaadinPropertyDescriptor.java
  24. 32
    0
      src/com/vaadin/data/util/converter/BooleanToStringConverter.java
  25. 72
    0
      src/com/vaadin/data/util/converter/Converter.java
  26. 7
    0
      src/com/vaadin/data/util/converter/ConverterFactory.java
  27. 50
    0
      src/com/vaadin/data/util/converter/DateToStringConverter.java
  28. 77
    0
      src/com/vaadin/data/util/converter/DefaultConverterFactory.java
  29. 38
    0
      src/com/vaadin/data/util/converter/DoubleToStringConverter.java
  30. 14
    0
      src/com/vaadin/data/util/converter/FieldValueConverterFactory.java
  31. 57
    0
      src/com/vaadin/data/util/converter/IntegerToStringConverter.java
  32. 32
    0
      src/com/vaadin/data/util/converter/LongToDateConverter.java
  33. 57
    0
      src/com/vaadin/data/util/converter/NumberToStringConverter.java
  34. 32
    0
      src/com/vaadin/data/util/converter/ReverseConverter.java
  35. 1
    1
      src/com/vaadin/data/util/filter/Compare.java
  36. 1
    1
      src/com/vaadin/data/util/filter/IsNull.java
  37. 8
    4
      src/com/vaadin/data/util/filter/SimpleStringFilter.java
  38. 28
    3
      src/com/vaadin/data/util/sqlcontainer/ColumnProperty.java
  39. 3
    2
      src/com/vaadin/data/util/sqlcontainer/RowItem.java
  40. 2
    2
      src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
  41. 2
    1
      src/com/vaadin/data/validator/AbstractStringValidator.java
  42. 44
    1
      src/com/vaadin/data/validator/AbstractValidator.java
  43. 1
    32
      src/com/vaadin/data/validator/CompositeValidator.java
  44. 0
    11
      src/com/vaadin/data/validator/NullValidator.java
  45. 2
    1
      src/com/vaadin/data/validator/StringLengthValidator.java
  46. 1
    1
      src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java
  47. 2
    0
      src/com/vaadin/ui/AbstractComponent.java
  48. 264
    113
      src/com/vaadin/ui/AbstractField.java
  49. 11
    7
      src/com/vaadin/ui/AbstractSelect.java
  50. 8
    8
      src/com/vaadin/ui/AbstractTextField.java
  51. 6
    5
      src/com/vaadin/ui/BaseFieldFactory.java
  52. 0
    21
      src/com/vaadin/ui/Button.java
  53. 6
    20
      src/com/vaadin/ui/CheckBox.java
  54. 0
    39
      src/com/vaadin/ui/CustomComponent.java
  55. 242
    0
      src/com/vaadin/ui/CustomField.java
  56. 12
    33
      src/com/vaadin/ui/DateField.java
  57. 7
    6
      src/com/vaadin/ui/DefaultFieldFactory.java
  58. 8
    19
      src/com/vaadin/ui/Field.java
  59. 2
    2
      src/com/vaadin/ui/FieldFactory.java
  60. 29
    43
      src/com/vaadin/ui/Form.java
  61. 1
    1
      src/com/vaadin/ui/FormFieldFactory.java
  62. 34
    11
      src/com/vaadin/ui/Label.java
  63. 0
    4
      src/com/vaadin/ui/NativeButton.java
  64. 10
    9
      src/com/vaadin/ui/ProgressIndicator.java
  65. 5
    5
      src/com/vaadin/ui/RichTextArea.java
  66. 4
    5
      src/com/vaadin/ui/Slider.java
  67. 67
    18
      src/com/vaadin/ui/Table.java
  68. 1
    1
      src/com/vaadin/ui/TableFieldFactory.java
  69. 1
    6
      tests/server-side/com/vaadin/data/util/BeanItemTest.java
  70. 45
    44
      tests/server-side/com/vaadin/data/util/NestedMethodPropertyTest.java
  71. 3
    5
      tests/server-side/com/vaadin/data/util/ObjectPropertyTest.java
  72. 5
    6
      tests/server-side/com/vaadin/data/util/PropertyDescriptorTest.java
  73. 3
    5
      tests/server-side/com/vaadin/data/util/PropertySetItemTest.java
  74. 3
    3
      tests/server-side/com/vaadin/data/util/filter/AbstractFilterTest.java
  75. 1
    3
      tests/server-side/com/vaadin/data/util/filter/AndOrFilterTest.java
  76. 1
    1
      tests/server-side/com/vaadin/data/util/filter/CompareFilterTest.java
  77. 1
    3
      tests/server-side/com/vaadin/data/util/filter/IsNullFilterTest.java
  78. 1
    3
      tests/server-side/com/vaadin/data/util/filter/NotFilterTest.java
  79. 2
    3
      tests/server-side/com/vaadin/data/util/filter/SimpleStringFilterTest.java
  80. 1
    1
      tests/server-side/com/vaadin/data/util/sqlcontainer/SQLContainerTest.java
  81. 1
    1
      tests/server-side/com/vaadin/data/util/sqlcontainer/filters/BetweenTest.java
  82. 63
    0
      tests/server-side/com/vaadin/tests/data/bean/Address.java
  83. 18
    0
      tests/server-side/com/vaadin/tests/data/bean/Country.java
  84. 133
    0
      tests/server-side/com/vaadin/tests/data/bean/Person.java
  85. 15
    0
      tests/server-side/com/vaadin/tests/data/bean/Sex.java
  86. 15
    4
      tests/server-side/com/vaadin/tests/server/TestSerialization.java
  87. 164
    0
      tests/server-side/com/vaadin/tests/server/component/abstractfield/AbstractFieldValueConversions.java
  88. 55
    0
      tests/server-side/com/vaadin/tests/server/component/abstractfield/DefaultConverterFactory.java
  89. 7
    7
      tests/server-side/com/vaadin/tests/server/component/textfield/TextFieldWithPropertyFormatter.java
  90. 5
    5
      tests/server-side/com/vaadin/tests/server/components/AbstractTestFieldValueChange.java
  91. 3
    2
      tests/server-side/com/vaadin/tests/server/components/TestComboBoxValueChange.java
  92. 3
    2
      tests/server-side/com/vaadin/tests/server/components/TestTextFieldValueChange.java
  93. 1
    1
      tests/server-side/com/vaadin/tests/server/validation/TestReadOnlyValidation.java
  94. 8
    1
      tests/testbench/com/vaadin/tests/CustomLayoutDemo.java
  95. 11
    2
      tests/testbench/com/vaadin/tests/PerformanceTestSubTreeCaching.java
  96. 12
    4
      tests/testbench/com/vaadin/tests/TestForChildComponentRendering.java
  97. 4
    4
      tests/testbench/com/vaadin/tests/TestForContainerFilterable.java
  98. 17
    4
      tests/testbench/com/vaadin/tests/TestForGridLayoutChildComponentRendering.java
  99. 6
    1
      tests/testbench/com/vaadin/tests/TestForPreconfiguredComponents.java
  100. 0
    0
      tests/testbench/com/vaadin/tests/TestForStyledUpload.java

+ 47
- 0
src/com/vaadin/Application.java View File

@@ -34,6 +34,9 @@ import java.util.regex.Pattern;
import com.vaadin.annotations.RootInitRequiresBrowserDetals;
import com.vaadin.annotations.RootTheme;
import com.vaadin.annotations.RootWidgetset;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.data.util.converter.ConverterFactory;
import com.vaadin.data.util.converter.DefaultConverterFactory;
import com.vaadin.service.ApplicationContext;
import com.vaadin.terminal.ApplicationResource;
import com.vaadin.terminal.CombinedRequest;
@@ -50,6 +53,7 @@ import com.vaadin.terminal.gwt.server.AbstractApplicationServlet;
import com.vaadin.terminal.gwt.server.ChangeVariablesErrorEvent;
import com.vaadin.terminal.gwt.server.WebApplicationContext;
import com.vaadin.ui.AbstractComponent;
import com.vaadin.ui.AbstractField;
import com.vaadin.ui.Root;
import com.vaadin.ui.Window;

@@ -512,6 +516,13 @@ public class Application implements Terminal.ErrorListener, Serializable {
*/
private Terminal.ErrorListener errorHandler = this;

/**
* The converter factory that is used for all fields in the application.
*/
// private ConverterFactory converterFactory = new
// DefaultConverterFactory();
private static ConverterFactory converterFactory = new DefaultConverterFactory();

private LinkedList<RequestHandler> requestHandlers = new LinkedList<RequestHandler>();

private int nextRootId = 0;
@@ -1198,6 +1209,42 @@ public class Application implements Terminal.ErrorListener, Serializable {
this.errorHandler = errorHandler;
}

/**
* Gets the {@link ConverterFactory} used to locate a suitable
* {@link Converter} for fields in the application.
*
* See {@link #setConverterFactory(ConverterFactory)} for more details
*
* @return The converter factory used in the application
*/
// public ConverterFactory getConverterFactory() {
// return converterFactory;
// }
// FIXME: Should not be static
public static ConverterFactory getConverterFactory() {
return converterFactory;
}

/**
* Sets the {@link ConverterFactory} used to locate a suitable
* {@link Converter} for fields in the application.
*
* The {@link ConverterFactory} is used to find a suitable converter when
* binding data to a UI component and the data type does not match the UI
* component type, e.g. binding a Double to a TextField (which is based on a
* String).
*
* The {@link Converter} for an individual field can be overridden using
* {@link AbstractField#setValueConverter(Converter)}.
*
* @param converterFactory
* The converter factory used in the application
*/
// FIXME: Should not be static
public static void setConverterFactory(ConverterFactory converterFactory) {
Application.converterFactory = converterFactory;
}

/**
* Contains the system messages used to notify the user about various
* critical situations that can occur.

+ 1
- 1
src/com/vaadin/data/Container.java View File

@@ -121,7 +121,7 @@ public interface Container extends Serializable {
* ID of the Property to retrieve
* @return Property with the given ID or <code>null</code>
*/
public Property getContainerProperty(Object itemId, Object propertyId);
public Property<?> getContainerProperty(Object itemId, Object propertyId);

/**
* Gets the data type of all Properties identified by the given Property ID.

+ 1
- 1
src/com/vaadin/data/Item.java View File

@@ -30,7 +30,7 @@ public interface Item extends Serializable {
* identifier of the Property to get
* @return the Property with the given ID or <code>null</code>
*/
public Property getItemProperty(Object id);
public Property<?> getItemProperty(Object id);

/**
* Gets the collection of IDs of all Properties stored in the Item.

+ 11
- 23
src/com/vaadin/data/Property.java View File

@@ -30,12 +30,15 @@ import java.io.Serializable;
* needs to be changed through the implementing class.
* </p>
*
* @param T
* type of values of the property
*
* @author IT Mill Ltd
* @version
* @VERSION@
* @since 3.0
*/
public interface Property extends Serializable {
public interface Property<T> extends Serializable {

/**
* Gets the value stored in the Property. The returned object is compatible
@@ -43,7 +46,7 @@ public interface Property extends Serializable {
*
* @return the value stored in the Property
*/
public Object getValue();
public T getValue();

/**
* Sets the value of the Property.
@@ -52,38 +55,23 @@ public interface Property extends Serializable {
* missing, one should declare the Property to be in read-only mode and
* throw <code>Property.ReadOnlyException</code> in this function.
* </p>
* Note : It is not required, but highly recommended to support setting the
* value also as a <code>String</code> in addition to the native type of the
* Property (as given by the <code>getType</code> method). If the
* <code>String</code> conversion fails or is unsupported, the method should
* throw <code>Property.ConversionException</code>. The string conversion
* should at least understand the format returned by the
* <code>toString</code> method of the Property.
*
* Note : Since Vaadin 7.0, setting the value of a non-String property as a
* String is no longer supported.
*
* @param newValue
* New value of the Property. This should be assignable to the
* type returned by getType, but also String type should be
* supported
* type returned by getType
*
* @throws Property.ReadOnlyException
* if the object is in read-only mode
* @throws Property.ConversionException
* if newValue can't be converted into the Property's native
* type directly or through String
* type directly or using a converter
*/
public void setValue(Object newValue) throws Property.ReadOnlyException,
Property.ConversionException;

/**
* Returns the value of the Property in human readable textual format. The
* return value should be assignable to the <code>setValue</code> method if
* the Property is not in read-only mode.
*
* @return <code>String</code> representation of the value stored in the
* Property
*/
public String toString();

/**
* Returns the type of the Property. The methods <code>getValue</code> and
* <code>setValue</code> must be compatible with this type: one must be able
@@ -93,7 +81,7 @@ public interface Property extends Serializable {
*
* @return type of the Property
*/
public Class<?> getType();
public Class<? extends T> getType();

/**
* Tests if the Property is in read-only mode. In read-only mode calls to

+ 7
- 12
src/com/vaadin/data/Validator.java View File

@@ -29,6 +29,13 @@ import com.vaadin.terminal.gwt.server.AbstractApplicationServlet;
* <p>
* Validators must not have any side effects.
* </p>
* <p>
* Since Vaadin 7, the method isValid(Object) does not exist in the interface -
* {@link #validate(Object)} should be used instead, and the exception caught
* where applicable. Concrete classes implementing {@link Validator} can still
* internally implement and use isValid(Object) for convenience or to ease
* migration from earlier Vaadin versions.
* </p>
*
* @author IT Mill Ltd.
* @version
@@ -49,18 +56,6 @@ public interface Validator extends Serializable {
*/
public void validate(Object value) throws Validator.InvalidValueException;

/**
* Tests if the given value is valid. This method must be symmetric with
* {@link #validate(Object)} so that {@link #validate(Object)} throws an
* error iff this method returns false.
*
* @param value
* the value to check
* @return <code>true</code> if the value is valid, <code>false</code>
* otherwise.
*/
public boolean isValid(Object value);

/**
* Exception that is thrown by a {@link Validator} when a value is invalid.
*

+ 44
- 9
src/com/vaadin/data/util/AbstractBeanContainer.java View File

@@ -104,8 +104,9 @@ public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends
+ " not found");
}
try {
Property property = pd.createProperty(bean);
return (IDTYPE) property.getValue();
Property<IDTYPE> property = (Property<IDTYPE>) pd
.createProperty(bean);
return property.getValue();
} catch (MethodException e) {
throw new IllegalArgumentException(e);
}
@@ -256,7 +257,7 @@ public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends
* @see com.vaadin.data.Container#getContainerProperty(java.lang.Object,
* java.lang.Object)
*/
public Property getContainerProperty(Object itemId, Object propertyId) {
public Property<?> getContainerProperty(Object itemId, Object propertyId) {
Item item = getItem(itemId);
if (item == null) {
return null;
@@ -371,7 +372,7 @@ public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends
* The id of the property
*/
private void addValueChangeListener(Item item, Object propertyId) {
Property property = item.getItemProperty(propertyId);
Property<?> property = item.getItemProperty(propertyId);
if (property instanceof ValueChangeNotifier) {
// avoid multiple notifications for the same property if
// multiple filters are in use
@@ -390,7 +391,7 @@ public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends
* The id of the property
*/
private void removeValueChangeListener(Item item, Object propertyId) {
Property property = item.getItemProperty(propertyId);
Property<?> property = item.getItemProperty(propertyId);
if (property instanceof ValueChangeNotifier) {
((ValueChangeNotifier) property).removeListener(this);
}
@@ -746,9 +747,9 @@ public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends
}

model.put(propertyId, propertyDescriptor);
for (BeanItem item : itemIdToItem.values()) {
item.addItemProperty(propertyId, propertyDescriptor
.createProperty((BEANTYPE) item.getBean()));
for (BeanItem<BEANTYPE> item : itemIdToItem.values()) {
item.addItemProperty(propertyId,
propertyDescriptor.createProperty(item.getBean()));
}

// Sends a change event
@@ -767,7 +768,6 @@ public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends
* @see NestedMethodProperty
*
* @param propertyId
* @param propertyType
* @return true if the property was added
*/
public boolean addNestedContainerProperty(String propertyId) {
@@ -775,6 +775,41 @@ public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends
propertyId, type));
}

/**
* Adds a nested container properties for all sub-properties of a named
* property to the container. The named property itself is removed from the
* model as its subproperties are added.
*
* All intermediate getters must exist and must return non-null values when
* the property value is accessed.
*
* @see NestedMethodProperty
* @see #addNestedContainerProperty(String)
*
* @param propertyId
*/
@SuppressWarnings("unchecked")
public void addNestedContainerBean(String propertyId) {
Class<?> propertyType = getType(propertyId);
LinkedHashMap<String, VaadinPropertyDescriptor<Object>> pds = BeanItem
.getPropertyDescriptors((Class<Object>) propertyType);
for (String subPropertyId : pds.keySet()) {
String qualifiedPropertyId = propertyId + "." + subPropertyId;
NestedPropertyDescriptor<BEANTYPE> pd = new NestedPropertyDescriptor<BEANTYPE>(
qualifiedPropertyId, (Class<BEANTYPE>) type);
model.put(qualifiedPropertyId, pd);
model.remove(propertyId);
for (BeanItem<BEANTYPE> item : itemIdToItem.values()) {
item.addItemProperty(propertyId,
pd.createProperty(item.getBean()));
item.removeItemProperty(propertyId);
}
}

// Sends a change event
fireContainerPropertySetChange();
}

@Override
public boolean removeContainerProperty(Object propertyId)
throws UnsupportedOperationException {

+ 22
- 7
src/com/vaadin/data/util/AbstractProperty.java View File

@@ -17,7 +17,7 @@ import com.vaadin.data.Property;
*
* @since 6.6
*/
public abstract class AbstractProperty implements Property,
public abstract class AbstractProperty<T> implements Property<T>,
Property.ValueChangeNotifier, Property.ReadOnlyStatusChangeNotifier {

/**
@@ -56,13 +56,28 @@ public abstract class AbstractProperty implements Property,

/**
* Returns the value of the <code>Property</code> in human readable textual
* format. The return value should be assignable to the
* <code>setValue</code> method if the Property is not in read-only mode.
* format.
*
* @return String representation of the value stored in the Property
* @deprecated use the property value directly, or {@link #getStringValue()}
* during migration period
*/
@Deprecated
@Override
public String toString() {
throw new UnsupportedOperationException(
"Use Property.getValue() instead of " + getClass()
+ ".toString()");
}

/**
* Returns the value of the <code>Property</code> in human readable textual
* format.
*
* @return String representation of the value stored in the Property
* @since 7.0
*/
public String getStringValue() {
final Object value = getValue();
if (value == null) {
return null;
@@ -76,8 +91,8 @@ public abstract class AbstractProperty implements Property,
* An <code>Event</code> object specifying the Property whose read-only
* status has been changed.
*/
protected class ReadOnlyStatusChangeEvent extends java.util.EventObject
implements Property.ReadOnlyStatusChangeEvent {
protected static class ReadOnlyStatusChangeEvent extends
java.util.EventObject implements Property.ReadOnlyStatusChangeEvent {

/**
* Constructs a new read-only status change event for this object.
@@ -144,8 +159,8 @@ public abstract class AbstractProperty implements Property,
* An <code>Event</code> object specifying the Property whose value has been
* changed.
*/
private class ValueChangeEvent extends java.util.EventObject implements
Property.ValueChangeEvent {
private static class ValueChangeEvent extends java.util.EventObject
implements Property.ValueChangeEvent {

/**
* Constructs a new value change event for this object.

+ 35
- 1
src/com/vaadin/data/util/BeanItem.java View File

@@ -12,9 +12,11 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* A wrapper class for adding the Item interface to any Java Bean.
@@ -162,7 +164,7 @@ public class BeanItem<BT> extends PropertysetItem {
final Method getMethod = pd.getReadMethod();
if ((getMethod != null)
&& getMethod.getDeclaringClass() != Object.class) {
VaadinPropertyDescriptor<BT> vaadinPropertyDescriptor = new MethodPropertyDescriptor(
VaadinPropertyDescriptor<BT> vaadinPropertyDescriptor = new MethodPropertyDescriptor<BT>(
pd.getName(), pd.getPropertyType(),
pd.getReadMethod(), pd.getWriteMethod());
pdMap.put(pd.getName(), vaadinPropertyDescriptor);
@@ -212,6 +214,38 @@ public class BeanItem<BT> extends PropertysetItem {
}
}

/**
* Expands nested bean properties by replacing a top-level property with
* some or all of its sub-properties. The expansion is not recursive.
*
* @param propertyId
* property id for the property whose sub-properties are to be
* expanded,
* @param subPropertyIds
* sub-properties to expand, all sub-properties are expanded if
* not specified
*/
public void expandProperty(String propertyId, String... subPropertyIds) {
Set<String> subPropertySet = new HashSet<String>(
Arrays.asList(subPropertyIds));

if (0 == subPropertyIds.length) {
// Enumerate all sub-properties
Class<?> propertyType = getItemProperty(propertyId).getType();
Map<String, ?> pds = getPropertyDescriptors(propertyType);
subPropertySet.addAll(pds.keySet());
}

for (String subproperty : subPropertySet) {
String qualifiedPropertyId = propertyId + "." + subproperty;
addItemProperty(qualifiedPropertyId,
new NestedMethodProperty<Object>(getBean(),
qualifiedPropertyId));
}

removeItemProperty(propertyId);
}

/**
* Gets the underlying JavaBean object.
*

+ 1
- 1
src/com/vaadin/data/util/ContainerHierarchicalWrapper.java View File

@@ -641,7 +641,7 @@ public class ContainerHierarchicalWrapper implements Container.Hierarchical,
* Container Don't add a JavaDoc comment here, we use the default
* documentation from implemented interface.
*/
public Property getContainerProperty(Object itemId, Object propertyId) {
public Property<?> getContainerProperty(Object itemId, Object propertyId) {
return container.getContainerProperty(itemId, propertyId);
}


+ 1
- 1
src/com/vaadin/data/util/ContainerOrderedWrapper.java View File

@@ -437,7 +437,7 @@ public class ContainerOrderedWrapper implements Container.Ordered,
* Container Don't add a JavaDoc comment here, we use the default
* documentation from implemented interface.
*/
public Property getContainerProperty(Object itemId, Object propertyId) {
public Property<?> getContainerProperty(Object itemId, Object propertyId) {
return container.getContainerProperty(itemId, propertyId);
}


+ 2
- 2
src/com/vaadin/data/util/DefaultItemSorter.java View File

@@ -122,8 +122,8 @@ public class DefaultItemSorter implements ItemSorter {
Item item1, Item item2) {

// Get the properties to compare
final Property property1 = item1.getItemProperty(propertyId);
final Property property2 = item2.getItemProperty(propertyId);
final Property<?> property1 = item1.getItemProperty(propertyId);
final Property<?> property2 = item2.getItemProperty(propertyId);

// Get the values to compare
final Object value1 = (property1 == null) ? null : property1.getValue();

+ 2
- 2
src/com/vaadin/data/util/FilesystemContainer.java View File

@@ -459,7 +459,7 @@ public class FilesystemContainer implements Container.Hierarchical {
* the property's ID.
* @return the requested property's value, or <code>null</code>
*/
public Property getContainerProperty(Object itemId, Object propertyId) {
public Property<?> getContainerProperty(Object itemId, Object propertyId) {

if (!(itemId instanceof File)) {
return null;
@@ -609,7 +609,7 @@ public class FilesystemContainer implements Container.Hierarchical {
* Gets the specified property of this file. Don't add a JavaDoc comment
* here, we use the default documentation from implemented interface.
*/
public Property getItemProperty(Object id) {
public Property<?> getItemProperty(Object id) {
return getContainerProperty(file, id);
}


+ 25
- 10
src/com/vaadin/data/util/IndexedContainer.java View File

@@ -76,7 +76,7 @@ public class IndexedContainer extends
/**
* Set of properties that are read-only.
*/
private HashSet<Property> readOnlyProperties = new HashSet<Property>();
private HashSet<Property<?>> readOnlyProperties = new HashSet<Property<?>>();

/**
* List of all Property value change event listeners listening all the
@@ -150,7 +150,7 @@ public class IndexedContainer extends
* @see com.vaadin.data.Container#getContainerProperty(java.lang.Object,
* java.lang.Object)
*/
public Property getContainerProperty(Object itemId, Object propertyId) {
public Property<?> getContainerProperty(Object itemId, Object propertyId) {
if (!containsId(itemId)) {
return null;
}
@@ -425,7 +425,7 @@ public class IndexedContainer extends
* @VERSION@
* @since 3.0
*/
public class ItemSetChangeEvent extends BaseItemSetChangeEvent {
public static class ItemSetChangeEvent extends BaseItemSetChangeEvent {

private final int addedItemIndex;

@@ -455,7 +455,7 @@ public class IndexedContainer extends
* @VERSION@
* @since 3.0
*/
private class PropertyValueChangeEvent extends EventObject implements
private static class PropertyValueChangeEvent extends EventObject implements
Property.ValueChangeEvent, Serializable {

private PropertyValueChangeEvent(Property source) {
@@ -680,7 +680,7 @@ public class IndexedContainer extends
*
* @see com.vaadin.data.Item#getItemProperty(java.lang.Object)
*/
public Property getItemProperty(Object id) {
public Property<?> getItemProperty(Object id) {
return new IndexedContainerProperty(itemId, id);
}

@@ -691,8 +691,8 @@ public class IndexedContainer extends
/**
* Gets the <code>String</code> representation of the contents of the
* Item. The format of the string is a space separated catenation of the
* <code>String</code> representations of the Properties contained by
* the Item.
* <code>String</code> representations of the values of the Properties
* contained by the Item.
*
* @return <code>String</code> representation of the Item contents
*/
@@ -702,7 +702,7 @@ public class IndexedContainer extends

for (final Iterator<?> i = propertyIds.iterator(); i.hasNext();) {
final Object propertyId = i.next();
retValue += getItemProperty(propertyId).toString();
retValue += getItemProperty(propertyId).getValue();
if (i.hasNext()) {
retValue += " ";
}
@@ -786,7 +786,7 @@ public class IndexedContainer extends
* @VERSION@
* @since 3.0
*/
private class IndexedContainerProperty implements Property,
private class IndexedContainerProperty implements Property<Object>,
Property.ValueChangeNotifier {

/**
@@ -910,9 +910,24 @@ public class IndexedContainer extends
*
* @return <code>String</code> representation of the value stored in the
* Property
* @deprecated use the property value directly, or
* {@link #getStringValue()} during migration period
*/
@Deprecated
@Override
public String toString() {
throw new UnsupportedOperationException(
"Use Property.getValue() instead of IndexedContainerProperty.toString()");
}

/**
* Returns the value of the <code>Property</code> in human readable
* textual format.
*
* @return String representation of the value stored in the Property
* @since 7.0
*/
public String getStringValue() {
final Object value = getValue();
if (value == null) {
return null;
@@ -1038,7 +1053,7 @@ public class IndexedContainer extends
getPropertySetChangeListeners()) : null);
nc.propertyValueChangeListeners = propertyValueChangeListeners != null ? (LinkedList<Property.ValueChangeListener>) propertyValueChangeListeners
.clone() : null;
nc.readOnlyProperties = readOnlyProperties != null ? (HashSet<Property>) readOnlyProperties
nc.readOnlyProperties = readOnlyProperties != null ? (HashSet<Property<?>>) readOnlyProperties
.clone() : null;
nc.singlePropertyValueChangeListeners = singlePropertyValueChangeListeners != null ? (Hashtable<Object, Map<Object, List<Property.ValueChangeListener>>>) singlePropertyValueChangeListeners
.clone() : null;

+ 13
- 12
src/com/vaadin/data/util/MethodProperty.java View File

@@ -47,7 +47,7 @@ import com.vaadin.util.SerializerHelper;
* @since 3.0
*/
@SuppressWarnings("serial")
public class MethodProperty<T> extends AbstractProperty {
public class MethodProperty<T> extends AbstractProperty<T> {

private static final Logger logger = Logger.getLogger(MethodProperty.class
.getName());
@@ -170,7 +170,7 @@ public class MethodProperty<T> extends AbstractProperty {
@SuppressWarnings("unchecked")
public MethodProperty(Object instance, String beanPropertyName) {

final Class beanClass = instance.getClass();
final Class<?> beanClass = instance.getClass();

// Assure that the first letter is upper cased (it is a common
// mistake to write firstName, not FirstName).
@@ -349,7 +349,7 @@ public class MethodProperty<T> extends AbstractProperty {
}

// Tests the parameter types
final Class[] c = m[i].getParameterTypes();
final Class<?>[] c = m[i].getParameterTypes();
if (c.length != getArgs.length) {

// not the right amount of parameters, try next method
@@ -398,7 +398,7 @@ public class MethodProperty<T> extends AbstractProperty {
}

// Checks parameter compatibility
final Class[] c = m[i].getParameterTypes();
final Class<?>[] c = m[i].getParameterTypes();
if (c.length != setArgs.length) {

// not the right amount of parameters, try next method
@@ -474,7 +474,9 @@ public class MethodProperty<T> extends AbstractProperty {
* {@link #setValue(Object newValue)} is called.
*/
@SuppressWarnings("unchecked")
public MethodProperty(Class type, Object instance, Method getMethod,
// cannot use "Class<? extends T>" because of automatic primitive type
// conversions
public MethodProperty(Class<?> type, Object instance, Method getMethod,
Method setMethod, Object[] getArgs, Object[] setArgs,
int setArgumentIndex) {

@@ -495,13 +497,13 @@ public class MethodProperty<T> extends AbstractProperty {
}

// Gets the return type from get method
type = convertPrimitiveType(type);
Class<? extends T> convertedType = (Class<? extends T>) convertPrimitiveType(type);

this.getMethod = getMethod;
this.setMethod = setMethod;
setArguments(getArgs, setArgs, setArgumentIndex);
this.instance = instance;
this.type = type;
this.type = convertedType;
}

/**
@@ -569,8 +571,7 @@ public class MethodProperty<T> extends AbstractProperty {
*
* @return type of the Property
*/
@SuppressWarnings("unchecked")
public final Class getType() {
public final Class<? extends T> getType() {
return type;
}

@@ -593,9 +594,9 @@ public class MethodProperty<T> extends AbstractProperty {
*
* @return the value of the Property
*/
public Object getValue() {
public T getValue() {
try {
return getMethod.invoke(instance, getArgs);
return (T) getMethod.invoke(instance, getArgs);
} catch (final Throwable e) {
throw new MethodException(this, e);
}
@@ -642,7 +643,6 @@ public class MethodProperty<T> extends AbstractProperty {
* native type directly or through <code>String</code>.
* @see #invokeSetMethod(Object)
*/
@SuppressWarnings("unchecked")
public void setValue(Object newValue) throws Property.ReadOnlyException,
Property.ConversionException {

@@ -675,6 +675,7 @@ public class MethodProperty<T> extends AbstractProperty {
// convert using a string constructor
try {
// Gets the string constructor
@SuppressWarnings("rawtypes")
final Constructor constr = type
.getConstructor(new Class[] { String.class });


+ 1
- 1
src/com/vaadin/data/util/MethodPropertyDescriptor.java View File

@@ -123,7 +123,7 @@ public class MethodPropertyDescriptor<BT> implements
return propertyType;
}

public Property createProperty(Object bean) {
public Property<?> createProperty(Object bean) {
return new MethodProperty<Object>(propertyType, bean, readMethod,
writeMethod);
}

+ 7
- 6
src/com/vaadin/data/util/NestedMethodProperty.java View File

@@ -26,7 +26,7 @@ import com.vaadin.data.util.MethodProperty.MethodException;
*
* @since 6.6
*/
public class NestedMethodProperty extends AbstractProperty {
public class NestedMethodProperty<T> extends AbstractProperty<T> {

// needed for de-serialization
private String propertyName;
@@ -43,7 +43,7 @@ public class NestedMethodProperty extends AbstractProperty {
*/
private Object instance;

private Class<?> type;
private Class<? extends T> type;

/* Special serialization to handle method references */
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
@@ -158,13 +158,14 @@ public class NestedMethodProperty extends AbstractProperty {
} catch (final NoSuchMethodException skipped) {
}

this.type = MethodProperty.convertPrimitiveType(type);
this.type = (Class<? extends T>) MethodProperty
.convertPrimitiveType(type);
this.propertyName = propertyName;
this.getMethods = getMethods;
this.setMethod = setMethod;
}

public Class<?> getType() {
public Class<? extends T> getType() {
return type;
}

@@ -179,13 +180,13 @@ public class NestedMethodProperty extends AbstractProperty {
*
* @return the value of the Property
*/
public Object getValue() {
public T getValue() {
try {
Object object = instance;
for (Method m : getMethods) {
object = m.invoke(object);
}
return object;
return (T) object;
} catch (final Throwable e) {
throw new MethodException(this, e);
}

+ 4
- 3
src/com/vaadin/data/util/NestedPropertyDescriptor.java View File

@@ -37,7 +37,8 @@ public class NestedPropertyDescriptor<BT> implements
public NestedPropertyDescriptor(String name, Class<BT> beanType)
throws IllegalArgumentException {
this.name = name;
NestedMethodProperty property = new NestedMethodProperty(beanType, name);
NestedMethodProperty<?> property = new NestedMethodProperty<Object>(
beanType, name);
this.propertyType = property.getType();
}

@@ -49,8 +50,8 @@ public class NestedPropertyDescriptor<BT> implements
return propertyType;
}

public Property createProperty(BT bean) {
return new NestedMethodProperty(bean, name);
public Property<?> createProperty(BT bean) {
return new NestedMethodProperty<Object>(bean, name);
}

}

+ 6
- 7
src/com/vaadin/data/util/ObjectProperty.java View File

@@ -19,7 +19,7 @@ import com.vaadin.data.Property;
* @since 3.0
*/
@SuppressWarnings("serial")
public class ObjectProperty<T> extends AbstractProperty {
public class ObjectProperty<T> extends AbstractProperty<T> {

/**
* The value contained by the Property.
@@ -48,9 +48,8 @@ public class ObjectProperty<T> extends AbstractProperty {
/**
* Creates a new instance of ObjectProperty with the given value and type.
*
* Any value of type Object is accepted because, if the type class contains
* a string constructor, the toString of the value is used to create the new
* value. See {@link #setValue(Object)}.
* Since Vaadin 7, only values of the correct type are accepted, and no
* automatic conversions are performed.
*
* @param value
* the Initial value of the Property.
@@ -58,7 +57,7 @@ public class ObjectProperty<T> extends AbstractProperty {
* the type of the value. The value must be assignable to given
* type.
*/
public ObjectProperty(Object value, Class<T> type) {
public ObjectProperty(T value, Class<T> type) {

// Set the values
this.type = type;
@@ -69,7 +68,7 @@ public class ObjectProperty<T> extends AbstractProperty {
* Creates a new instance of ObjectProperty with the given value, type and
* read-only mode status.
*
* Any value of type Object is accepted, see
* Since Vaadin 7, only the correct type of values is accepted, see
* {@link #ObjectProperty(Object, Class)}.
*
* @param value
@@ -80,7 +79,7 @@ public class ObjectProperty<T> extends AbstractProperty {
* @param readOnly
* Sets the read-only mode.
*/
public ObjectProperty(Object value, Class<T> type, boolean readOnly) {
public ObjectProperty(T value, Class<T> type, boolean readOnly) {
this(value, type);
setReadOnly(readOnly);
}

+ 21
- 19
src/com/vaadin/data/util/PropertyFormatter.java View File

@@ -29,16 +29,20 @@ import com.vaadin.data.Property;
* standard "1.0" notation with more zeroes.
* </p>
*
* @param T
* type of the underlying property (a PropertyFormatter is always a
* Property&lt;String&gt;)
*
* @author IT Mill Ltd.
* @since 5.3.0
*/
@SuppressWarnings("serial")
public abstract class PropertyFormatter extends AbstractProperty implements
Property.Viewer, Property.ValueChangeListener,
public abstract class PropertyFormatter<T> extends AbstractProperty<String>
implements Property.Viewer, Property.ValueChangeListener,
Property.ReadOnlyStatusChangeListener {

/** Datasource that stores the actual value. */
Property dataSource;
Property<T> dataSource;

/**
* Construct a new {@code PropertyFormatter} that is not connected to any
@@ -57,7 +61,7 @@ public abstract class PropertyFormatter extends AbstractProperty implements
* @param propertyDataSource
* to connect this property to.
*/
public PropertyFormatter(Property propertyDataSource) {
public PropertyFormatter(Property<T> propertyDataSource) {

setPropertyDataSource(propertyDataSource);
}
@@ -68,7 +72,7 @@ public abstract class PropertyFormatter extends AbstractProperty implements
* @return the current data source as a Property, or <code>null</code> if
* none defined.
*/
public Property getPropertyDataSource() {
public Property<T> getPropertyDataSource() {
return dataSource;
}

@@ -99,7 +103,7 @@ public abstract class PropertyFormatter extends AbstractProperty implements
.removeListener(this);
}
readOnly = isReadOnly();
prevValue = toString();
prevValue = getStringValue();
}

dataSource = newDataSource;
@@ -117,7 +121,7 @@ public abstract class PropertyFormatter extends AbstractProperty implements
if (isReadOnly() != readOnly) {
fireReadOnlyStatusChange();
}
String newVal = toString();
String newVal = getStringValue();
if ((prevValue == null && newVal != null)
|| (prevValue != null && !prevValue.equals(newVal))) {
fireValueChange();
@@ -125,7 +129,7 @@ public abstract class PropertyFormatter extends AbstractProperty implements
}

/* Documented in the interface */
public Class getType() {
public Class<String> getType() {
return String.class;
}

@@ -135,22 +139,20 @@ public abstract class PropertyFormatter extends AbstractProperty implements
* @return If the datasource returns null, this is null. Otherwise this is
* String given by format().
*/
public Object getValue() {
return toString();
public String getValue() {
return getStringValue();
}

/**
* Get the formatted value.
* Get the formatted value. For PropertyFormatter, this is identical with
* {@link #getValue()}.
*
* @return If the datasource returns null, this is null. Otherwise this is
* String given by format().
*/
@Override
public String toString() {
if (dataSource == null) {
return null;
}
Object value = dataSource.getValue();
public String getStringValue() {
T value = dataSource == null ? null : dataSource.getValue();
if (value == null) {
return null;
}
@@ -173,7 +175,7 @@ public abstract class PropertyFormatter extends AbstractProperty implements
* datasource.
* @return
*/
abstract public String format(Object value);
abstract public String format(T value);

/**
* Parse string and convert it to format compatible with datasource.
@@ -187,7 +189,7 @@ public abstract class PropertyFormatter extends AbstractProperty implements
* Any type of exception can be thrown to indicate that the
* conversion was not succesful.
*/
abstract public Object parse(String formattedValue) throws Exception;
abstract public T parse(String formattedValue) throws Exception;

/**
* Sets the Property's read-only mode to the specified status.
@@ -215,7 +217,7 @@ public abstract class PropertyFormatter extends AbstractProperty implements
} else {
try {
dataSource.setValue(parse(newValue.toString()));
if (!newValue.equals(toString())) {
if (!newValue.equals(getStringValue())) {
fireValueChange();
}
} catch (ConversionException e) {

+ 5
- 5
src/com/vaadin/data/util/PropertysetItem.java View File

@@ -34,7 +34,7 @@ public class PropertysetItem implements Item, Item.PropertySetChangeNotifier,
/**
* Mapping from property id to property.
*/
private HashMap<Object, Property> map = new HashMap<Object, Property>();
private HashMap<Object, Property<?>> map = new HashMap<Object, Property<?>>();

/**
* List of all property ids to maintain the order.
@@ -57,7 +57,7 @@ public class PropertysetItem implements Item, Item.PropertySetChangeNotifier,
* the identifier of the Property to get.
* @return the Property with the given ID or <code>null</code>
*/
public Property getItemProperty(Object id) {
public Property<?> getItemProperty(Object id) {
return map.get(id);
}

@@ -143,7 +143,7 @@ public class PropertysetItem implements Item, Item.PropertySetChangeNotifier,

for (final Iterator<?> i = getItemPropertyIds().iterator(); i.hasNext();) {
final Object propertyId = i.next();
retValue += getItemProperty(propertyId).toString();
retValue += getItemProperty(propertyId).getValue();
if (i.hasNext()) {
retValue += " ";
}
@@ -163,7 +163,7 @@ public class PropertysetItem implements Item, Item.PropertySetChangeNotifier,
* @VERSION@
* @since 3.0
*/
private class PropertySetChangeEvent extends EventObject implements
private static class PropertySetChangeEvent extends EventObject implements
Item.PropertySetChangeEvent {

private PropertySetChangeEvent(Item source) {
@@ -262,7 +262,7 @@ public class PropertysetItem implements Item, Item.PropertySetChangeNotifier,
npsi.list = list != null ? (LinkedList<Object>) list.clone() : null;
npsi.propertySetChangeListeners = propertySetChangeListeners != null ? (LinkedList<PropertySetChangeListener>) propertySetChangeListeners
.clone() : null;
npsi.map = (HashMap<Object, Property>) map.clone();
npsi.map = (HashMap<Object, Property<?>>) map.clone();

return npsi;
}

+ 4
- 3
src/com/vaadin/data/util/QueryContainer.java View File

@@ -136,7 +136,8 @@ public class QueryContainer implements Container, Container.Ordered,
for (int i = 1; i <= count; i++) {
final String columnName = metadata.getColumnName(i);
list.add(columnName);
final Property p = getContainerProperty(new Integer(1), columnName);
final Property<?> p = getContainerProperty(new Integer(1),
columnName);
propertyTypes.put(columnName,
p == null ? Object.class : p.getType());
}
@@ -228,7 +229,7 @@ public class QueryContainer implements Container, Container.Ordered,
* otherwise.
*/

public synchronized Property getContainerProperty(Object itemId,
public synchronized Property<?> getContainerProperty(Object itemId,
Object propertyId) {
if (!(itemId instanceof Integer && propertyId instanceof String)) {
return null;
@@ -531,7 +532,7 @@ public class QueryContainer implements Container, Container.Ordered,
* identifier of the Property to get
* @return the Property with the given ID or <code>null</code>
*/
public Property getItemProperty(Object propertyId) {
public Property<?> getItemProperty(Object propertyId) {
return getContainerProperty(id, propertyId);
}


+ 3
- 3
src/com/vaadin/data/util/TextFileProperty.java View File

@@ -26,7 +26,7 @@ import java.nio.charset.Charset;
*
*/
@SuppressWarnings("serial")
public class TextFileProperty extends AbstractProperty {
public class TextFileProperty extends AbstractProperty<String> {
private File file;
private Charset charset = null;
@@ -64,7 +64,7 @@ public class TextFileProperty extends AbstractProperty {
*
* @see com.vaadin.data.Property#getType()
*/
public Class<?> getType() {
public Class<String> getType() {
return String.class;
}
@@ -73,7 +73,7 @@ public class TextFileProperty extends AbstractProperty {
*
* @see com.vaadin.data.Property#getValue()
*/
public Object getValue() {
public String getValue() {
if (file == null) {
return null;
}

+ 1
- 1
src/com/vaadin/data/util/VaadinPropertyDescriptor.java View File

@@ -39,5 +39,5 @@ public interface VaadinPropertyDescriptor<BT> extends Serializable {
* @param bean
* @return
*/
public Property createProperty(BT bean);
public Property<?> createProperty(BT bean);
}

+ 32
- 0
src/com/vaadin/data/util/converter/BooleanToStringConverter.java View File

@@ -0,0 +1,32 @@
package com.vaadin.data.util.converter;
import java.util.Locale;
public class BooleanToStringConverter implements Converter<Boolean, String> {
public Boolean convertFromTargetToSource(String value, Locale locale) {
try {
return Boolean.valueOf(value);
} catch (Exception e) {
throw new ConversionException("Cannot convert " + value
+ " to Boolean");
}
}
public String convertFromSourceToTarget(Boolean value, Locale locale) {
if (value == null) {
return "";
}
return value.toString();
}
public Class<Boolean> getSourceType() {
return Boolean.class;
}
public Class<String> getTargetType() {
return String.class;
}
}

+ 72
- 0
src/com/vaadin/data/util/converter/Converter.java View File

@@ -0,0 +1,72 @@
package com.vaadin.data.util.converter;
import java.io.Serializable;
import java.util.Locale;
public interface Converter<SOURCE, TARGET> extends Serializable {
public SOURCE convertFromTargetToSource(TARGET value, Locale locale)
throws ConversionException;
public TARGET convertFromSourceToTarget(SOURCE value, Locale locale)
throws ConversionException;
public Class<SOURCE> getSourceType();
public Class<TARGET> getTargetType();
/**
* An exception that signals that the value passed to #convert or
* Converter.convertFromTargetToSource could not be converted.
*
* @author Vaadin Ltd
* @version
* @VERSION@
* @since 7.0
*/
public class ConversionException extends RuntimeException {
/**
* Constructs a new <code>ConversionException</code> without a detail
* message.
*/
public ConversionException() {
}
/**
* Constructs a new <code>ConversionException</code> with the specified
* detail message.
*
* @param msg
* the detail message
*/
public ConversionException(String msg) {
super(msg);
}
/**
* Constructs a new {@code ConversionException} with the specified
* cause.
*
* @param cause
* The cause of the the exception
*/
public ConversionException(Throwable cause) {
super(cause);
}
/**
* Constructs a new <code>ConversionException</code> with the specified
* detail message and cause.
*
* @param message
* the detail message
* @param cause
* The cause of the the exception
*/
public ConversionException(String message, Throwable cause) {
super(message, cause);
}
}
}

+ 7
- 0
src/com/vaadin/data/util/converter/ConverterFactory.java View File

@@ -0,0 +1,7 @@
package com.vaadin.data.util.converter;
public interface ConverterFactory {
<SOURCE, TARGET> Converter<SOURCE, TARGET> createConverter(
Class<SOURCE> sourceType, Class<TARGET> targetType);
}

+ 50
- 0
src/com/vaadin/data/util/converter/DateToStringConverter.java View File

@@ -0,0 +1,50 @@
package com.vaadin.data.util.converter;
import java.text.DateFormat;
import java.text.ParsePosition;
import java.util.Date;
import java.util.Locale;
public class DateToStringConverter implements Converter<Date, String> {
public Date convertFromTargetToSource(String value, Locale locale)
throws com.vaadin.data.util.converter.Converter.ConversionException {
if (value == null) {
return null;
}
ParsePosition parsePosition = new ParsePosition(0);
Date parsedValue = getFormat(locale).parse(value, parsePosition);
if (parsePosition.getIndex() != value.length()) {
throw new ConversionException("Could not convert '" + value
+ "' to " + getTargetType().getName());
}
return parsedValue;
}
public String convertFromSourceToTarget(Date value, Locale locale)
throws com.vaadin.data.util.converter.Converter.ConversionException {
if (value == null) {
return null;
}
return getFormat(locale).format(value);
}
protected DateFormat getFormat(Locale locale) {
DateFormat f = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
DateFormat.MEDIUM, locale);
f.setLenient(false);
return f;
}
public Class<Date> getSourceType() {
return Date.class;
}
public Class<String> getTargetType() {
return String.class;
}
}

+ 77
- 0
src/com/vaadin/data/util/converter/DefaultConverterFactory.java View File

@@ -0,0 +1,77 @@
package com.vaadin.data.util.converter;
import java.util.Date;
public class DefaultConverterFactory implements ConverterFactory {
public <SOURCE, TARGET> Converter<SOURCE, TARGET> createConverter(
Class<SOURCE> sourceType, Class<TARGET> targetType) {
Converter<SOURCE, TARGET> converter = findConverter(sourceType,
targetType);
if (converter != null) {
System.out.println(getClass().getName() + " created a "
+ converter.getClass());
return converter;
}
// Try to find a reverse converter
Converter<TARGET, SOURCE> reverseConverter = findConverter(targetType,
sourceType);
if (reverseConverter != null) {
System.out.println(getClass().getName() + " created a reverse "
+ reverseConverter.getClass());
return new ReverseConverter<SOURCE, TARGET>(reverseConverter);
}
System.out.println(getClass().getName()
+ " could not find a converter for " + sourceType.getName()
+ " to " + targetType.getName() + " conversion");
return null;
}
protected <SOURCE, TARGET> Converter<SOURCE, TARGET> findConverter(
Class<SOURCE> sourceType, Class<TARGET> targetType) {
if (targetType == String.class) {
// TextField converters and more
Converter<SOURCE, TARGET> converter = (Converter<SOURCE, TARGET>) createStringConverter(sourceType);
if (converter != null) {
return converter;
}
} else if (targetType == Date.class) {
// DateField converters and more
Converter<SOURCE, TARGET> converter = (Converter<SOURCE, TARGET>) createDateConverter(sourceType);
if (converter != null) {
return converter;
}
}
return null;
}
protected Converter<?, Date> createDateConverter(Class<?> sourceType) {
if (Long.class.isAssignableFrom(sourceType)) {
return new LongToDateConverter();
} else {
return null;
}
}
protected Converter<?, String> createStringConverter(Class<?> sourceType) {
if (Double.class.isAssignableFrom(sourceType)) {
return new DoubleToStringConverter();
} else if (Integer.class.isAssignableFrom(sourceType)) {
return new IntegerToStringConverter();
} else if (Boolean.class.isAssignableFrom(sourceType)) {
return new BooleanToStringConverter();
} else if (Number.class.isAssignableFrom(sourceType)) {
return new NumberToStringConverter();
} else if (Date.class.isAssignableFrom(sourceType)) {
return new DateToStringConverter();
} else {
return null;
}
}
}

+ 38
- 0
src/com/vaadin/data/util/converter/DoubleToStringConverter.java View File

@@ -0,0 +1,38 @@
package com.vaadin.data.util.converter;
import java.text.NumberFormat;
import java.text.ParsePosition;
import java.util.Locale;
public class DoubleToStringConverter implements Converter<Double, String> {
protected NumberFormat getFormatter(Locale locale) {
return NumberFormat.getNumberInstance(locale);
}
public Double convertFromTargetToSource(String value, Locale locale) {
ParsePosition parsePosition = new ParsePosition(0);
Number parsedValue = getFormatter(locale).parse(value, parsePosition);
if (parsePosition.getIndex() != value.length()) {
throw new ConversionException("Could not convert '" + value
+ "' to " + getTargetType().getName());
}
return parsedValue.doubleValue();
}
public String convertFromSourceToTarget(Double value, Locale locale) {
if (value == null) {
return null;
}
return getFormatter(locale).format(value);
}
public Class<Double> getSourceType() {
return Double.class;
}
public Class<String> getTargetType() {
return String.class;
}
}

+ 14
- 0
src/com/vaadin/data/util/converter/FieldValueConverterFactory.java View File

@@ -0,0 +1,14 @@
package com.vaadin.data.util.converter;
//package com.vaadin.data;
//
//import java.io.Serializable;
//
//import com.vaadin.ui.Field;
//
//public interface FieldValueConverterFactory extends Serializable {
//
// <SOURCE, TARGET> Converter<SOURCE, TARGET> createConverter(
// Field<SOURCE> field, Item item, Object propertyId,
// Class<TARGET> targetType);
//
// }

+ 57
- 0
src/com/vaadin/data/util/converter/IntegerToStringConverter.java View File

@@ -0,0 +1,57 @@
package com.vaadin.data.util.converter;
import java.text.NumberFormat;
import java.text.ParsePosition;
import java.util.Locale;
public class IntegerToStringConverter implements Converter<Integer, String> {
protected NumberFormat getFormatter(Locale locale) {
if (locale == null) {
return NumberFormat.getIntegerInstance();
} else {
return NumberFormat.getIntegerInstance(locale);
}
}
public Integer convertFromTargetToSource(String value, Locale locale) {
if (value == null) {
return null;
}
// Remove extra spaces
value = value.trim();
// Parse and detect errors. If the full string was not used, it is
// an error.
ParsePosition parsePosition = new ParsePosition(0);
Number parsedValue = getFormatter(locale).parse(value, parsePosition);
if (parsePosition.getIndex() != value.length()) {
throw new ConversionException("Could not convert '" + value
+ "' to " + getTargetType().getName());
}
if (parsedValue == null) {
// Convert "" to null
return null;
}
return parsedValue.intValue();
}
public String convertFromSourceToTarget(Integer value, Locale locale) {
if (value == null) {
return null;
}
return getFormatter(locale).format(value);
}
public Class<Integer> getSourceType() {
return Integer.class;
}
public Class<String> getTargetType() {
return String.class;
}
}

+ 32
- 0
src/com/vaadin/data/util/converter/LongToDateConverter.java View File

@@ -0,0 +1,32 @@
package com.vaadin.data.util.converter;
import java.util.Date;
import java.util.Locale;
public class LongToDateConverter implements Converter<Long, Date> {
public Long convertFromTargetToSource(Date value, Locale locale) {
if (value == null) {
return null;
}
return value.getTime();
}
public Date convertFromSourceToTarget(Long value, Locale locale) {
if (value == null) {
return null;
}
return new Date(value);
}
public Class<Long> getSourceType() {
return Long.class;
}
public Class<Date> getTargetType() {
return Date.class;
}
}

+ 57
- 0
src/com/vaadin/data/util/converter/NumberToStringConverter.java View File

@@ -0,0 +1,57 @@
package com.vaadin.data.util.converter;
import java.text.NumberFormat;
import java.text.ParsePosition;
import java.util.Locale;
public class NumberToStringConverter implements Converter<Number, String> {
protected NumberFormat getFormatter(Locale locale) {
if (locale == null) {
return NumberFormat.getNumberInstance();
} else {
return NumberFormat.getNumberInstance(locale);
}
}
public Number convertFromTargetToSource(String value, Locale locale) {
if (value == null) {
return null;
}
// Remove extra spaces
value = value.trim();
// Parse and detect errors. If the full string was not used, it is
// an error.
ParsePosition parsePosition = new ParsePosition(0);
Number parsedValue = getFormatter(locale).parse(value, parsePosition);
if (parsePosition.getIndex() != value.length()) {
throw new ConversionException("Could not convert '" + value
+ "' to " + getTargetType().getName());
}
if (parsedValue == null) {
// Convert "" to null
return null;
}
return parsedValue;
}
public String convertFromSourceToTarget(Number value, Locale locale) {
if (value == null) {
return null;
}
return getFormatter(locale).format(value);
}
public Class<Number> getSourceType() {
return Number.class;
}
public Class<String> getTargetType() {
return String.class;
}
}

+ 32
- 0
src/com/vaadin/data/util/converter/ReverseConverter.java View File

@@ -0,0 +1,32 @@
package com.vaadin.data.util.converter;
import java.util.Locale;
public class ReverseConverter<SOURCE, TARGET> implements
Converter<SOURCE, TARGET> {
private Converter<TARGET, SOURCE> realConverter;
public ReverseConverter(Converter<TARGET, SOURCE> realConverter) {
this.realConverter = realConverter;
}
public SOURCE convertFromTargetToSource(TARGET value, Locale locale)
throws com.vaadin.data.util.converter.Converter.ConversionException {
return realConverter.convertFromSourceToTarget(value, locale);
}
public TARGET convertFromSourceToTarget(SOURCE value, Locale locale)
throws com.vaadin.data.util.converter.Converter.ConversionException {
return realConverter.convertFromTargetToSource(value, locale);
}
public Class<SOURCE> getSourceType() {
return realConverter.getTargetType();
}
public Class<TARGET> getTargetType() {
return realConverter.getSourceType();
}
}

+ 1
- 1
src/com/vaadin/data/util/filter/Compare.java View File

@@ -228,7 +228,7 @@ public abstract class Compare implements Filter {
}

public boolean passesFilter(Object itemId, Item item) {
final Property p = item.getItemProperty(getPropertyId());
final Property<?> p = item.getItemProperty(getPropertyId());
if (null == p) {
return false;
}

+ 1
- 1
src/com/vaadin/data/util/filter/IsNull.java View File

@@ -35,7 +35,7 @@ public final class IsNull implements Filter {

public boolean passesFilter(Object itemId, Item item)
throws UnsupportedOperationException {
final Property p = item.getItemProperty(getPropertyId());
final Property<?> p = item.getItemProperty(getPropertyId());
if (null == p) {
return false;
}

+ 8
- 4
src/com/vaadin/data/util/filter/SimpleStringFilter.java View File

@@ -40,12 +40,16 @@ public final class SimpleStringFilter implements Filter {
}

public boolean passesFilter(Object itemId, Item item) {
final Property p = item.getItemProperty(propertyId);
if (p == null || p.toString() == null) {
final Property<?> p = item.getItemProperty(propertyId);
if (p == null) {
return false;
}
final String value = ignoreCase ? p.toString().toLowerCase() : p
.toString();
Object propertyValue = p.getValue();
if (propertyValue == null) {
return false;
}
final String value = ignoreCase ? propertyValue.toString()
.toLowerCase() : propertyValue.toString();
if (onlyMatchPrefix) {
if (!value.startsWith(filterString)) {
return false;

+ 28
- 3
src/com/vaadin/data/util/sqlcontainer/ColumnProperty.java View File

@@ -168,13 +168,38 @@ final public class ColumnProperty implements Property {
return propertyId;
}

/**
* Returns the value of the Property in human readable textual format.
*
* @see java.lang.Object#toString()
* @deprecated get the string representation from the value, or use
* getStringValue() during migration
*/
@Deprecated
@Override
public String toString() {
Object val = getValue();
if (val == null) {
throw new UnsupportedOperationException(
"Use ColumnProperty.getValue() instead of ColumnProperty.toString()");
}

/**
* Returns the (UI type) value of the field converted to a String using
* toString().
*
* This method exists to help migration from the use of Property.toString()
* to get the field value - for new applications, access getValue()
* directly. This method may disappear in future Vaadin versions.
*
* @return string representation of the field value or null if the value is
* null
* @since 7.0
*/
public String getStringValue() {
final Object value = getValue();
if (value == null) {
return null;
}
return val.toString();
return value.toString();
}

public void setOwner(RowItem owner) {

+ 3
- 2
src/com/vaadin/data/util/sqlcontainer/RowItem.java View File

@@ -48,7 +48,7 @@ public final class RowItem implements Item {
this.id = id;
}

public Property getItemProperty(Object id) {
public Property<?> getItemProperty(Object id) {
if (id instanceof String && id != null) {
for (ColumnProperty cp : properties) {
if (id.equals(cp.getPropertyId())) {
@@ -113,7 +113,8 @@ public final class RowItem implements Item {
s.append("|");
s.append(propId.toString());
s.append(":");
s.append(getItemProperty(propId).toString());
Object value = getItemProperty(propId).getValue();
s.append((null != value) ? value.toString() : null);
}
return s.toString();
}

+ 2
- 2
src/com/vaadin/data/util/sqlcontainer/SQLContainer.java View File

@@ -227,7 +227,7 @@ public class SQLContainer implements Container, Container.Filterable,
* @see com.vaadin.data.Container#getContainerProperty(java.lang.Object,
* java.lang.Object)
*/
public Property getContainerProperty(Object itemId, Object propertyId) {
public Property<?> getContainerProperty(Object itemId, Object propertyId) {
Item item = getItem(itemId);
if (item == null) {
return null;
@@ -1435,7 +1435,7 @@ public class SQLContainer implements Container, Container.Filterable,
* Simple ItemSetChangeEvent implementation.
*/
@SuppressWarnings("serial")
public class ItemSetChangeEvent extends EventObject implements
public static class ItemSetChangeEvent extends EventObject implements
Container.ItemSetChangeEvent {

private ItemSetChangeEvent(SQLContainer source) {

+ 2
- 1
src/com/vaadin/data/validator/AbstractStringValidator.java View File

@@ -51,7 +51,8 @@ public abstract class AbstractStringValidator extends AbstractValidator {
* @return true if the value (or its toString()) is a valid string, false
* otherwise
*/
public boolean isValid(Object value) {
@Override
protected boolean internalIsValid(Object value) {
if (value == null) {
return true;
}

+ 44
- 1
src/com/vaadin/data/validator/AbstractValidator.java View File

@@ -21,6 +21,11 @@ import com.vaadin.data.Validator;
* {@link InvalidValueException#getHtmlMessage()} and throw such exceptions from
* {@link #validate(Object)}.
* </p>
* <p>
* Since Vaadin 7, subclasses can either implement {@link #validate(Object)}
* directly or implement {@link #internalIsValid(Object)} when migrating legacy
* applications. To check validity, {@link #validate(Object)} should be used.
* </p>
*
* @author IT Mill Ltd.
* @version
@@ -47,8 +52,46 @@ public abstract class AbstractValidator implements Validator {
this.errorMessage = errorMessage;
}

/**
* Since Vaadin 7, subclasses of AbstractValidator should override
* {@link #internalIsValid(Object)} or {@link #validate(Object)} instead of
* {@link #isValid(Object)}. {@link #validate(Object)} should be used to
* check values.
*
* This method may disappear in future Vaadin versions.
*
* @param value
* @return true if the value is valid
* @deprecated override {@link #internalIsValid(Object)} or
* {@link #validate(Object)} instead of {@link #isValid(Object)}
* and use {@link #validate(Object)} to check value validity
*/
@Deprecated
protected final boolean isValid(Object value) {
try {
validate(value);
return true;
} catch (InvalidValueException e) {
return false;
}
}

/**
* Internally check the validity of a value. This method can be overridden
* in subclasses if customization of the error message is not needed -
* otherwise, subclasses should override {@link #validate(Object)} instead.
*
* This method should not be called from outside the validator class itself.
*
* @param value
* @return
*/
protected boolean internalIsValid(Object value) {
return false;
}

public void validate(Object value) throws InvalidValueException {
if (!isValid(value)) {
if (!internalIsValid(value)) {
String message = errorMessage.replace("{0}", String.valueOf(value));
throw new InvalidValueException(message);
}

+ 1
- 32
src/com/vaadin/data/validator/CompositeValidator.java View File

@@ -10,6 +10,7 @@ import java.util.LinkedList;
import java.util.List;

import com.vaadin.data.Validator;
import com.vaadin.data.validator.CompositeValidator.CombinationMode;

/**
* The <code>CompositeValidator</code> allows you to chain (compose) many
@@ -130,38 +131,6 @@ public class CompositeValidator extends AbstractValidator {
}
}

/**
* Checks the validity of the the given value. The value is valid, if:
* <ul>
* <li>{@link CombinationMode.AND}: All of the sub-validators are valid
* <li>{@link CombinationMode.OR}: Any of the sub-validators are valid
* </ul>
*
* @param value
* the value to check.
*/
public boolean isValid(Object value) {
switch (mode) {
case AND:
for (Validator v : validators) {
if (!v.isValid(value)) {
return false;
}
}
return true;

case OR:
for (Validator v : validators) {
if (v.isValid(value)) {
return true;
}
}
return false;
}
throw new IllegalStateException(
"The validator is in unsupported operation mode");
}

/**
* Gets the mode of the validator.
*

+ 0
- 11
src/com/vaadin/data/validator/NullValidator.java View File

@@ -50,17 +50,6 @@ public class NullValidator implements Validator {
}
}

/**
* Tests if the given value is valid.
*
* @param value
* the value to validate.
* @returns <code>true</code> for valid value, otherwise <code>false</code>.
*/
public boolean isValid(Object value) {
return onlyNullAllowed ? value == null : value != null;
}

/**
* Returns <code>true</code> if nulls are allowed otherwise
* <code>false</code>.

+ 2
- 1
src/com/vaadin/data/validator/StringLengthValidator.java View File

@@ -61,7 +61,8 @@ public class StringLengthValidator extends AbstractValidator {
* the value to validate.
* @return <code>true</code> for valid value, otherwise <code>false</code>.
*/
public boolean isValid(Object value) {
@Override
protected boolean internalIsValid(Object value) {
if (value == null) {
return allowNull;
}

+ 1
- 1
src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java View File

@@ -1337,7 +1337,7 @@ public abstract class AbstractCommunicationManager implements

if (owner instanceof AbstractField) {
try {
handled = ((AbstractField) owner).handleError(errorEvent);
handled = ((AbstractField<?>) owner).handleError(errorEvent);
} catch (Exception handlerException) {
/*
* If there is an error in the component error handler we pass

+ 2
- 0
src/com/vaadin/ui/AbstractComponent.java View File

@@ -327,6 +327,8 @@ public abstract class AbstractComponent implements Component, MethodEventSource
*/
public void setLocale(Locale locale) {
this.locale = locale;

// FIXME: Reload value if there is a converter
requestRepaint();
}


+ 264
- 113
src/com/vaadin/ui/AbstractField.java View File

@@ -12,11 +12,14 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;

import com.vaadin.Application;
import com.vaadin.data.Buffered;
import com.vaadin.data.Property;
import com.vaadin.data.Validatable;
import com.vaadin.data.Validator;
import com.vaadin.data.Validator.InvalidValueException;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.data.util.converter.ConverterFactory;
import com.vaadin.event.Action;
import com.vaadin.event.ShortcutAction;
import com.vaadin.event.ShortcutListener;
@@ -52,8 +55,8 @@ import com.vaadin.terminal.PaintTarget;
* @since 3.0
*/
@SuppressWarnings("serial")
public abstract class AbstractField extends AbstractComponent implements Field,
Property.ReadOnlyStatusChangeListener,
public abstract class AbstractField<T> extends AbstractComponent implements
Field<T>, Property.ReadOnlyStatusChangeListener,
Property.ReadOnlyStatusChangeNotifier, Action.ShortcutNotifier {

/* Private members */
@@ -61,12 +64,17 @@ public abstract class AbstractField extends AbstractComponent implements Field,
/**
* Value of the abstract field.
*/
private Object value;
private T value;

/**
* A converter used to convert from the data model type to the field type
* and vice versa.
*/
private Converter<Object, T> valueConverter = null;
/**
* Connected data-source.
*/
private Property dataSource = null;
private Property<?> dataSource = null;

/**
* The list of validators.
@@ -178,11 +186,16 @@ public abstract class AbstractField extends AbstractComponent implements Field,
&& getErrorMessage() != null;
}

/*
* Gets the field type Don't add a JavaDoc comment here, we use the default
* documentation from the implemented interface.
/**
* Returns the type of the Field. The methods <code>getValue</code> and
* <code>setValue</code> must be compatible with this type: one must be able
* to safely cast the value returned from <code>getValue</code> to the given
* type and pass any variable assignable to this type as an argument to
* <code>setValue</code>.
*
* @return the type of the Field
*/
public abstract Class<?> getType();
public abstract Class<? extends T> getType();

/**
* The abstract field is read only also if the data source is in read only
@@ -230,13 +243,14 @@ public abstract class AbstractField extends AbstractComponent implements Field,
public void commit() throws Buffered.SourceException, InvalidValueException {
if (dataSource != null && !dataSource.isReadOnly()) {
if ((isInvalidCommitted() || isValid())) {
final Object newValue = getValue();
final T fieldValue = getFieldValue();
try {

// Commits the value to datasource.
valueWasModifiedByDataSourceDuringCommit = false;
committingValueToDataSource = true;
dataSource.setValue(newValue);
getPropertyDataSource().setValue(
convertToDataSource(fieldValue));

} catch (final Throwable e) {

@@ -259,8 +273,8 @@ public abstract class AbstractField extends AbstractComponent implements Field,
boolean repaintNeeded = false;

// The abstract field is not modified anymore
if (modified) {
modified = false;
if (isModified()) {
setModified(false);
repaintNeeded = true;
}

@@ -287,12 +301,11 @@ public abstract class AbstractField extends AbstractComponent implements Field,
if (dataSource != null) {

// Gets the correct value from datasource
Object newValue;
T newFieldValue;
try {

// Discards buffer by overwriting from datasource
newValue = String.class == getType() ? dataSource.toString()
: dataSource.getValue();
newFieldValue = convertFromDataSource(getDataSourceValue());

// If successful, remove set the buffering state to be ok
if (currentBufferedSourceException != null) {
@@ -300,6 +313,7 @@ public abstract class AbstractField extends AbstractComponent implements Field,
requestRepaint();
}
} catch (final Throwable e) {
// FIXME: What should really be done here if conversion fails?

// Sets the buffering state
currentBufferedSourceException = new Buffered.SourceException(
@@ -311,22 +325,43 @@ public abstract class AbstractField extends AbstractComponent implements Field,
}

final boolean wasModified = isModified();
modified = false;
setModified(false);

// If the new value differs from the previous one
if ((newValue == null && value != null)
|| (newValue != null && !newValue.equals(value))) {
setInternalValue(newValue);
if (!equals(newFieldValue, getInternalValue())) {
setInternalValue(newFieldValue);
fireValueChange(false);
}

// If the value did not change, but the modification status did
else if (wasModified) {
} else if (wasModified) {
// If the value did not change, but the modification status did
requestRepaint();
}
}
}

private Object getDataSourceValue() {
return dataSource.getValue();
}

/**
* Returns the value that is or should be displayed in the field. This is
* always of type T.
*
* This method should return the same as
* convertFromDataSource(getDataSourceValue()) if there are no buffered
* changes in the field.
*
* @return The value of the field
*/
private T getFieldValue() {
// Give the value from abstract buffers if the field if possible
if (dataSource == null || !isReadThrough() || isModified()) {
return getInternalValue();
}

// There is no buffered value so use whatever the data model provides
return convertFromDataSource(getDataSourceValue());
}

/*
* Has the field been modified since the last commit()? Don't add a JavaDoc
* comment here, we use the default documentation from the implemented
@@ -336,6 +371,10 @@ public abstract class AbstractField extends AbstractComponent implements Field,
return modified;
}

private void setModified(boolean modified) {
this.modified = 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.
@@ -379,9 +418,8 @@ public abstract class AbstractField extends AbstractComponent implements Field,
return;
}
readThroughMode = readThrough;
if (!isModified() && readThroughMode && dataSource != null) {
setInternalValue(String.class == getType() ? dataSource.toString()
: dataSource.getValue());
if (!isModified() && readThroughMode && getPropertyDataSource() != null) {
setInternalValue(convertFromDataSource(getDataSourceValue()));
fireValueChange(false);
}
}
@@ -392,14 +430,34 @@ public abstract class AbstractField extends AbstractComponent implements Field,
* Returns the value of the Property in human readable textual format.
*
* @see java.lang.Object#toString()
* @deprecated get the string representation from the data source, or use
* getStringValue() during migration
*/
@Deprecated
@Override
public String toString() {
final Object value = getValue();
throw new UnsupportedOperationException(
"Use Property.getValue() instead of " + getClass()
+ ".toString()");
}

/**
* Returns the (UI type) value of the field converted to a String.
*
* This method exists to help migration from the use of Property.toString()
* to get the field value. For new applications, it is often better to
* access getValue() directly.
*
* @return string representation of the field value or null if the value is
* null
* @since 7.0
*/
public String getStringValue() {
final Object value = getFieldValue();
if (value == null) {
return null;
}
return getValue().toString();
return value.toString();
}

/**
@@ -407,67 +465,63 @@ public abstract class AbstractField extends AbstractComponent implements Field,
*
* <p>
* 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.
* entered to the field.
* </p>
*
* <p>
* Note that the object returned is compatible with getType(). For example,
* if the type is String, this returns Strings even when the underlying
* datasource is of some other type. In order to access the datasources
* native type, use getPropertyDatasource().getValue() instead.
* datasource is of some other type. In order to access the native value of
* the datasource, use getDataSourceValue() instead.
* </p>
*
* <p>
* Note that when you extend AbstractField, you must reimplement this method
* if datasource.getValue() is not assignable to class returned by getType()
* AND getType() is not String. In case of Strings, getValue() calls
* datasource.toString() instead of datasource.getValue().
* Since Vaadin 7.0, no implicit conversions between other data types and
* String are performed, but a value converter is used if set.
* </p>
*
* @return the current value of the field.
* @throws Property.ConversionException
*/
public Object getValue() {

// Give the value from abstract buffers if the field if possible
if (dataSource == null || !isReadThrough() || isModified()) {
return value;
}

Object newValue = String.class == getType() ? dataSource.toString()
: dataSource.getValue();

return newValue;
public T getValue() {
return getFieldValue();
}

/**
* Sets the value of the field.
*
* @param newValue
* @param newFieldValue
* 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);
public void setValue(Object newFieldValue)
throws Property.ReadOnlyException, Property.ConversionException {
// This check is needed as long as setValue accepts Object instead of T
if (newFieldValue != null) {
if (!getType().isAssignableFrom(newFieldValue.getClass())) {
throw new ConversionException("Value of type "
+ newFieldValue.getClass() + " cannot be assigned to "
+ getClass().getName());
}
}
setValue((T) newFieldValue, false);
}

/**
* Sets the value of the field.
*
* @param newValue
* @param newFieldValue
* 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)
protected void setValue(T newFieldValue, boolean repaintIsNotNeeded)
throws Property.ReadOnlyException, Property.ConversionException {

if ((newValue == null && value != null)
|| (newValue != null && !newValue.equals(value))) {
if (!equals(newFieldValue, getInternalValue())) {

// Read only fields can not be changed
if (isReadOnly()) {
@@ -486,14 +540,14 @@ public abstract class AbstractField extends AbstractComponent implements Field,
if (v != null) {
for (final Iterator<Validator> i = v.iterator(); i
.hasNext();) {
(i.next()).validate(newValue);
(i.next()).validate(newFieldValue);
}
}
}

// Changes the value
setInternalValue(newValue);
modified = dataSource != null;
setInternalValue(newFieldValue);
setModified(dataSource != null);

valueWasModifiedByDataSourceDuringCommit = false;
// In write through mode , try to commit
@@ -503,10 +557,11 @@ public abstract class AbstractField extends AbstractComponent implements Field,

// Commits the value to datasource
committingValueToDataSource = true;
dataSource.setValue(newValue);
getPropertyDataSource().setValue(
convertToDataSource(newFieldValue));

// The buffer is now unmodified
modified = false;
setModified(false);

} catch (final Throwable e) {

@@ -542,6 +597,13 @@ public abstract class AbstractField extends AbstractComponent implements Field,
}
}

private static boolean equals(Object value1, Object value2) {
if (value1 == null) {
return value2 == null;
}
return value1.equals(value2);
}

/* External data source */

/**
@@ -584,7 +646,7 @@ public abstract class AbstractField extends AbstractComponent implements Field,
public void setPropertyDataSource(Property newDataSource) {

// Saves the old value
final Object oldValue = value;
final Object oldValue = getInternalValue();

// Stops listening the old data source changes
if (dataSource != null
@@ -602,17 +664,23 @@ public abstract class AbstractField extends AbstractComponent implements Field,
// Sets the new data source
dataSource = newDataSource;

// Check if the current converter is compatible. If not, get a new one
if (newDataSource == null) {
setValueConverter(null);
} else if (!isValueConverterType(newDataSource.getType())) {
setValueConverterFromFactory(newDataSource.getType());
}
// Gets the value from source
try {
if (dataSource != null) {
setInternalValue(String.class == getType() ? dataSource
.toString() : dataSource.getValue());
T fieldValue = convertFromDataSource(getDataSourceValue());
setInternalValue(fieldValue);
}
modified = false;
setModified(false);
} catch (final Throwable e) {
currentBufferedSourceException = new Buffered.SourceException(this,
e);
modified = true;
setModified(true);
}

// Listens the new data source if possible
@@ -637,12 +705,91 @@ public abstract class AbstractField extends AbstractComponent implements Field,
}

// Fires value change if the value has changed
T value = getInternalValue();
if ((value != oldValue)
&& ((value != null && !value.equals(oldValue)) || value == null)) {
fireValueChange(false);
}
}

private void setValueConverterFromFactory(Class<?> datamodelType) {
// FIXME Use thread local to get application
ConverterFactory factory = Application.getConverterFactory();

Converter<?, T> converter = (Converter<?, T>) factory.createConverter(
datamodelType, getType());

setValueConverter(converter);
}

private boolean isValueConverterType(Class<?> type) {
if (getValueConverter() == null) {
return false;
}
return getValueConverter().getSourceType().isAssignableFrom(type);
}

@SuppressWarnings("unchecked")
private T convertFromDataSource(Object newValue) {
if (valueConverter != null) {
return valueConverter.convertFromSourceToTarget(newValue,
getLocale());
}
if (newValue == null) {
return null;
}

if (getType().isAssignableFrom(newValue.getClass())) {
return (T) newValue;
} else {
throw new ConversionException(
"Unable to convert value of type "
+ newValue.getClass().getName()
+ " to "
+ getType()
+ ". No value converter is set and the types are not compatible.");
}
}

private Object convertToDataSource(T fieldValue)
throws Converter.ConversionException {
if (valueConverter != null) {
/*
* If there is a value converter, always use it. It must convert or
* throw an exception.
*/
return valueConverter.convertFromTargetToSource(fieldValue,
getLocale());
}

if (fieldValue == null) {
// Null should always be passed through the converter but if there
// is no converter we can safely return null
return null;
}

// check that the value class is compatible with the data source type
// (if data source set) or field type
Class<?> type;
if (getPropertyDataSource() != null) {
type = getPropertyDataSource().getType();
} else {
type = getType();
}

if (type.isAssignableFrom(fieldValue.getClass())) {
return fieldValue;
} else {
throw new Converter.ConversionException(
"Unable to convert value of type "
+ fieldValue.getClass().getName()
+ " to "
+ type.getName()
+ ". No value converter is set and the types are not compatible.");

}
}

/* Validation */

/**
@@ -691,32 +838,21 @@ public abstract class AbstractField extends AbstractComponent implements Field,
* empty. If the field is empty it is considered valid if it is not required
* and invalid otherwise. Validators are never checked for empty fields.
*
* In most cases, {@link #validate()} should be used instead of
* {@link #isValid()} to also get the error message.
*
* @return <code>true</code> if all registered validators claim that the
* current value is valid or if the field is empty and not required,
* <code>false</code> otherwise.
*/
public boolean isValid() {

if (isEmpty()) {
if (isRequired()) {
return false;
} else {
return true;
}
}

if (validators == null) {
try {
validate();
return true;
} catch (InvalidValueException e) {
return false;
}

final Object value = getValue();
for (final Iterator<Validator> i = validators.iterator(); i.hasNext();) {
if (!(i.next()).isValid(value)) {
return false;
}
}

return true;
}

/**
@@ -748,12 +884,12 @@ public abstract class AbstractField extends AbstractComponent implements Field,
// Initialize temps
Validator.InvalidValueException firstError = null;
LinkedList<InvalidValueException> errors = null;
final Object value = getValue();
final Object fieldValue = getFieldValue();

// Gets all the validation errors
for (final Iterator<Validator> i = validators.iterator(); i.hasNext();) {
try {
(i.next()).validate(value);
(i.next()).validate(fieldValue);
} catch (final Validator.InvalidValueException e) {
if (firstError == null) {
firstError = e;
@@ -942,8 +1078,8 @@ public abstract class AbstractField extends AbstractComponent implements Field,
* @VERSION@
* @since 3.0
*/
public class ReadOnlyStatusChangeEvent extends Component.Event implements
Property.ReadOnlyStatusChangeEvent, Serializable {
public static class ReadOnlyStatusChangeEvent extends Component.Event
implements Property.ReadOnlyStatusChangeEvent, Serializable {

/**
* New instance of text change event.
@@ -1007,10 +1143,8 @@ public abstract class AbstractField extends AbstractComponent implements Field,
public void valueChange(Property.ValueChangeEvent event) {
if (isReadThrough()) {
if (committingValueToDataSource) {
boolean propertyNotifiesOfTheBufferedValue = event
.getProperty().getValue() == value
|| (value != null && value.equals(event.getProperty()
.getValue()));
boolean propertyNotifiesOfTheBufferedValue = equals(event
.getProperty().getValue(), getInternalValue());
if (!propertyNotifiesOfTheBufferedValue) {
/*
* Property (or chained property like PropertyFormatter) now
@@ -1033,7 +1167,7 @@ public abstract class AbstractField extends AbstractComponent implements Field,
}

private void readValueFromProperty(Property.ValueChangeEvent event) {
setInternalValue(event.getProperty().getValue());
setInternalValue(convertFromDataSource(event.getProperty().getValue()));
}

@Override
@@ -1049,25 +1183,6 @@ public abstract class AbstractField extends AbstractComponent implements Field,
super.focus();
}

/**
* 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.
* @deprecated use e.g.
* {@link DefaultFieldFactory#createFieldByPropertyType(Class)}
* instead
*/
@Deprecated
public static AbstractField constructField(Class<?> propertyType) {
return (AbstractField) DefaultFieldFactory
.createFieldByPropertyType(propertyType);
}

/*
* (non-Javadoc)
*
@@ -1087,6 +1202,14 @@ public abstract class AbstractField extends AbstractComponent implements Field,
requestRepaint();
}

/**
*
* @return
*/
protected T getInternalValue() {
return value;
}

/**
* Sets the internal field value. This is purely used by AbstractField to
* change the internal Field value. It does not trigger valuechange events.
@@ -1096,7 +1219,7 @@ public abstract class AbstractField extends AbstractComponent implements Field,
* @param newValue
* the new value to be set.
*/
protected void setInternalValue(Object newValue) {
protected void setInternalValue(T newValue) {
value = newValue;
if (validators != null && !validators.isEmpty()) {
requestRepaint();
@@ -1168,7 +1291,7 @@ public abstract class AbstractField extends AbstractComponent implements Field,
* also treats empty string as "empty".
*/
protected boolean isEmpty() {
return (getValue() == null);
return (getFieldValue() == null);
}

/**
@@ -1271,4 +1394,32 @@ public abstract class AbstractField extends AbstractComponent implements Field,
focusable.focus();
}
}

/**
* Gets the converter used to convert the property data source value to the
* field value.
*
* @return The converter or null if none is set.
*/
public Converter<Object, T> getValueConverter() {
return valueConverter;
}

/**
* Sets the converter used to convert the property data source value to the
* field value. The converter must have a target type that matches the field
* type.
*
* The source for the converter is the data model and the target is the
* field.
*
* @param valueConverter
* The new value converter to use.
*/
public void setValueConverter(Converter<?, T> valueConverter) {
//
this.valueConverter = (Converter<Object, T>) valueConverter;
requestRepaint();
}

}

+ 11
- 7
src/com/vaadin/ui/AbstractSelect.java View File

@@ -55,7 +55,8 @@ import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation;
* @since 5.0
*/
@SuppressWarnings("serial")
public abstract class AbstractSelect extends AbstractField implements
// TODO currently cannot specify type more precisely in case of multi-select
public abstract class AbstractSelect extends AbstractField<Object> implements
Container, Container.Viewer, Container.PropertySetChangeListener,
Container.PropertySetChangeNotifier, Container.ItemSetChangeNotifier,
Container.ItemSetChangeListener {
@@ -729,7 +730,7 @@ public abstract class AbstractSelect extends AbstractField implements
*
* @see com.vaadin.data.Container#getContainerProperty(Object, Object)
*/
public Property getContainerProperty(Object itemId, Object propertyId) {
public Property<?> getContainerProperty(Object itemId, Object propertyId) {
return items.getContainerProperty(itemId, propertyId);
}

@@ -1077,10 +1078,13 @@ public abstract class AbstractSelect extends AbstractField implements
break;

case ITEM_CAPTION_MODE_PROPERTY:
final Property p = getContainerProperty(itemId,
final Property<?> p = getContainerProperty(itemId,
getItemCaptionPropertyId());
if (p != null) {
caption = p.toString();
Object value = p.getValue();
if (value != null) {
caption = value.toString();
}
}
break;
}
@@ -1125,7 +1129,7 @@ public abstract class AbstractSelect extends AbstractField implements
return null;
}

final Property ip = getContainerProperty(itemId,
final Property<?> ip = getContainerProperty(itemId,
getItemIconPropertyId());
if (ip == null) {
return null;
@@ -1704,7 +1708,7 @@ public abstract class AbstractSelect extends AbstractField implements
Collection<?> pids = i.getItemPropertyIds();
if (pids != null) {
for (Iterator<?> it = pids.iterator(); it.hasNext();) {
Property p = i.getItemProperty(it.next());
Property<?> p = i.getItemProperty(it.next());
if (p != null
&& p instanceof Property.ValueChangeNotifier) {
((Property.ValueChangeNotifier) p)
@@ -1716,7 +1720,7 @@ public abstract class AbstractSelect extends AbstractField implements
}
break;
case ITEM_CAPTION_MODE_PROPERTY:
final Property p = getContainerProperty(itemId,
final Property<?> p = getContainerProperty(itemId,
getItemCaptionPropertyId());
if (p != null && p instanceof Property.ValueChangeNotifier) {
((Property.ValueChangeNotifier) p)

+ 8
- 8
src/com/vaadin/ui/AbstractTextField.java View File

@@ -20,7 +20,7 @@ import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.terminal.gwt.client.ui.VTextField;

public abstract class AbstractTextField extends AbstractField implements
public abstract class AbstractTextField extends AbstractField<String> implements
BlurNotifier, FocusNotifier, TextChangeNotifier {

/**
@@ -171,8 +171,8 @@ public abstract class AbstractTextField extends AbstractField implements
}

@Override
public Object getValue() {
Object v = super.getValue();
public String getValue() {
String v = super.getValue();
if (format == null || v == null) {
return v;
}
@@ -250,7 +250,7 @@ public abstract class AbstractTextField extends AbstractField implements
}

@Override
public Class getType() {
public Class<String> getType() {
return String.class;
}

@@ -373,7 +373,7 @@ public abstract class AbstractTextField extends AbstractField implements

@Override
protected boolean isEmpty() {
return super.isEmpty() || toString().length() == 0;
return super.isEmpty() || getStringValue().length() == 0;
}

/**
@@ -456,7 +456,7 @@ public abstract class AbstractTextField extends AbstractField implements
}

@Override
protected void setInternalValue(Object newValue) {
protected void setInternalValue(String newValue) {
if (changingVariables && !textChangeEventPending) {

/*
@@ -513,7 +513,7 @@ public abstract class AbstractTextField extends AbstractField implements
* case. AbstractField optimizes value change if the existing value is
* reset. Also we need to force repaint if the flag is on.
*/
if(lastKnownTextContent != null) {
if (lastKnownTextContent != null) {
lastKnownTextContent = null;
requestRepaint();
}
@@ -751,4 +751,4 @@ public abstract class AbstractTextField extends AbstractField implements
removeListener(BlurEvent.EVENT_ID, BlurEvent.class, listener);
}

}
}

+ 6
- 5
src/com/vaadin/ui/BaseFieldFactory.java View File

@@ -40,7 +40,7 @@ public class BaseFieldFactory implements FieldFactory {
*
* @see com.vaadin.ui.FieldFactory#createField(Class, Component)
*/
public Field createField(Class<?> type, Component uiContext) {
public Field<?> createField(Class<?> type, Component uiContext) {
return DefaultFieldFactory.createFieldByPropertyType(type);
}

@@ -49,7 +49,7 @@ public class BaseFieldFactory implements FieldFactory {
*
* @see com.vaadin.ui.FieldFactory#createField(Property, Component)
*/
public Field createField(Property property, Component uiContext) {
public Field<?> createField(Property property, Component uiContext) {
if (property != null) {
return createField(property.getType(), uiContext);
} else {
@@ -62,9 +62,10 @@ public class BaseFieldFactory implements FieldFactory {
*
* @see com.vaadin.ui.FieldFactory#createField(Item, Object, Component)
*/
public Field createField(Item item, Object propertyId, Component uiContext) {
public Field<?> createField(Item item, Object propertyId,
Component uiContext) {
if (item != null && propertyId != null) {
final Field f = createField(item.getItemProperty(propertyId),
final Field<?> f = createField(item.getItemProperty(propertyId),
uiContext);
if (f instanceof AbstractComponent) {
String name = DefaultFieldFactory
@@ -81,7 +82,7 @@ public class BaseFieldFactory implements FieldFactory {
* @see com.vaadin.ui.FieldFactory#createField(com.vaadin.data.Container,
* java.lang.Object, java.lang.Object, com.vaadin.ui.Component)
*/
public Field createField(Container container, Object itemId,
public Field<?> createField(Container container, Object itemId,
Object propertyId, Component uiContext) {
return createField(container.getContainerProperty(itemId, propertyId),
uiContext);

+ 0
- 21
src/com/vaadin/ui/Button.java View File

@@ -75,27 +75,6 @@ public class Button extends AbstractComponent implements
addListener(listener);
}

/**
* Creates a new push button with a method listening button clicks. Using
* this method is discouraged because it cannot be checked during
* compilation. Use
* {@link #Button(String, com.vaadin.ui.Button.ClickListener)} instead. The
* method must have either no parameters, or only one parameter of
* Button.ClickEvent type.
*
* @param caption
* the Button caption.
* @param target
* the Object having the method for listening button clicks.
* @param methodName
* the name of the method in target object, that receives button
* click events.
*/
public Button(String caption, Object target, String methodName) {
this(caption);
addListener(ClickEvent.class, target, methodName);
}

/**
* Paints the content of this component.
*

+ 6
- 20
src/com/vaadin/ui/CheckBox.java View File

@@ -16,11 +16,12 @@ import com.vaadin.terminal.PaintTarget;
import com.vaadin.terminal.gwt.client.ui.VCheckBox;

@ClientWidget(com.vaadin.terminal.gwt.client.ui.VCheckBox.class)
public class CheckBox extends AbstractField {
public class CheckBox extends AbstractField<Boolean> {
/**
* Creates a new checkbox.
*/
public CheckBox() {
setValue(Boolean.FALSE);
}

/**
@@ -54,13 +55,13 @@ public class CheckBox extends AbstractField {
* the Initial state of the switch-button.
* @param dataSource
*/
public CheckBox(String caption, Property dataSource) {
public CheckBox(String caption, Property<?> dataSource) {
this(caption);
setPropertyDataSource(dataSource);
}

@Override
public Class<?> getType() {
public Class<Boolean> getType() {
return Boolean.class;
}

@@ -68,7 +69,7 @@ public class CheckBox extends AbstractField {
public void paintContent(PaintTarget target) throws PaintException {
super.paintContent(target);

target.addVariable(this, VCheckBox.VARIABLE_STATE, booleanValue());
target.addVariable(this, VCheckBox.VARIABLE_STATE, getValue());
}

@Override
@@ -79,7 +80,7 @@ public class CheckBox extends AbstractField {
// Gets the new and old states
final Boolean newValue = (Boolean) variables
.get(VCheckBox.VARIABLE_STATE);
final Boolean oldValue = (Boolean) getValue();
final Boolean oldValue = getValue();

// The event is only sent if the switch state is changed
if (newValue != null && !newValue.equals(oldValue)) {
@@ -114,19 +115,4 @@ public class CheckBox extends AbstractField {

}

/**
* Get the boolean value of the checkbox state.
*
* @return True iff the checkbox is checked.
* @deprecated in Vaadin 7.0.0. Retained to ease migration from Vaadin 6
*/
@Deprecated
public boolean booleanValue() {
// FIXME: How should null really be handled? A default converter that
// converts it to false? The only UI values supported are true and
// false.
Boolean value = (Boolean) getValue();
return (null == value) ? false : value.booleanValue();
}

}

+ 0
- 39
src/com/vaadin/ui/CustomComponent.java View File

@@ -35,11 +35,6 @@ public class CustomComponent extends AbstractComponentContainer {
*/
private Component root = null;

/**
* Type of the component.
*/
private String componentType = null;

/**
* Constructs a new custom component.
*
@@ -115,43 +110,9 @@ public class CustomComponent extends AbstractComponentContainer {
+ " can be painted");
}

if (getComponentType() != null) {
target.addAttribute("type", getComponentType());
}
root.paint(target);
}

/**
* Gets the component type.
*
* The component type is textual type of the component. This is included in
* the UIDL as component tag attribute.
*
* @deprecated not more useful as the whole tag system has been removed
*
* @return the component type.
*/
@Deprecated
public String getComponentType() {
return componentType;
}

/**
* Sets the component type.
*
* The component type is textual type of the component. This is included in
* the UIDL as component tag attribute.
*
* @deprecated not more useful as the whole tag system has been removed
*
* @param componentType
* the componentType to set.
*/
@Deprecated
public void setComponentType(String componentType) {
this.componentType = componentType;
}

private class ComponentIterator implements Iterator<Component>,
Serializable {
boolean first = getCompositionRoot() != null;

+ 242
- 0
src/com/vaadin/ui/CustomField.java View File

@@ -0,0 +1,242 @@
package com.vaadin.ui;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Iterator;

import com.vaadin.data.Property;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.terminal.gwt.client.ui.VCustomComponent;

/**
* A {@link Field} whose UI content can be constructed by the user, enabling the
* creation of e.g. form fields by composing Vaadin components. Customization of
* both the visual presentation and the logic of the field is possible.
*
* Subclasses must implement {@link #getType()} and {@link #createContent()}.
*
* Most custom fields can simply compose a user interface that calls the methods
* {@link #setInternalValue(Object)} and {@link #getInternalValue()} when
* necessary.
*
* It is also possible to override {@link #commit()},
* {@link #setPropertyDataSource(Property)} and other logic of the field.
*
* @since 7.0
*/
@ClientWidget(VCustomComponent.class)
public abstract class CustomField<T> extends AbstractField<T> implements
ComponentContainer {

/**
* The root component implementing the custom component.
*/
private Component root = null;

/**
* Constructs a new custom field.
*
* <p>
* The component is implemented by wrapping the methods of the composition
* root component given as parameter. The composition root must be set
* before the component can be used.
* </p>
*/
public CustomField() {
// expand horizontally by default
setWidth(100, UNITS_PERCENTAGE);
}

/**
* Constructs the content and notifies it that the {@link CustomField} is
* attached to a window.
*
* @see com.vaadin.ui.Component#attach()
*/
@Override
public void attach() {
root = getContent();
super.attach();
getContent().setParent(this);
getContent().attach();

fireComponentAttachEvent(getContent());
}

/**
* Notifies the content that the {@link CustomField} is detached from a
* window.
*
* @see com.vaadin.ui.Component#detach()
*/
@Override
public void detach() {
super.detach();
getContent().detach();
}

@Override
public void paintContent(PaintTarget target) throws PaintException {
if (getContent() == null) {
throw new IllegalStateException(
"Content component or layout of the field must be set before the "
+ getClass().getName() + " can be painted");
}

getContent().paint(target);
}

/**
* Returns the content of the
*
* @return
*/
protected Component getContent() {
if (null == root) {
root = createContent();
}
return root;
}

/**
* Create the content component or layout for the field. Subclasses of
* {@link CustomField} should implement this method.
*
* Note that this method is called when the CustomField is attached to a
* layout or when {@link #getContent()} is called explicitly for the first
* time. It is only called once for a {@link CustomField}.
*
* @return
*/
protected abstract Component createContent();

private void requestContentRepaint() {
if (getParent() == null) {
// skip repaint - not yet attached
return;
}
if (getContent() instanceof ComponentContainer) {
((ComponentContainer) getContent()).requestRepaintAll();
} else {
getContent().requestRepaint();
}
}

// Size related methods
// TODO might not be necessary to override but following the pattern from
// AbstractComponentContainer

@Override
public void setHeight(float height, int unit) {
super.setHeight(height, unit);
requestContentRepaint();
}

@Override
public void setWidth(float height, int unit) {
super.setWidth(height, unit);
requestContentRepaint();
}

// ComponentContainer methods

private class ComponentIterator implements Iterator<Component>,
Serializable {
boolean first = getContent() != null;

public boolean hasNext() {
return first;
}

public Component next() {
first = false;
return getContent();
}

public void remove() {
throw new UnsupportedOperationException();
}
}

public Iterator<Component> getComponentIterator() {
return new ComponentIterator();
}

public int getComponentCount() {
return (null != getContent()) ? 1 : 0;
}

public void requestRepaintAll() {
requestRepaint();

requestContentRepaint();
}

/**
* Fires the component attached event. This should be called by the
* addComponent methods after the component have been added to this
* container.
*
* @param component
* the component that has been added to this container.
*/
protected void fireComponentAttachEvent(Component component) {
fireEvent(new ComponentAttachEvent(this, component));
}

// TODO remove these methods when ComponentContainer interface is cleaned up

public void addComponent(Component c) {
throw new UnsupportedOperationException();
}

public void removeComponent(Component c) {
throw new UnsupportedOperationException();
}

public void removeAllComponents() {
throw new UnsupportedOperationException();
}

public void replaceComponent(Component oldComponent, Component newComponent) {
throw new UnsupportedOperationException();
}

public void moveComponentsFrom(ComponentContainer source) {
throw new UnsupportedOperationException();
}

private static final Method COMPONENT_ATTACHED_METHOD;

static {
try {
COMPONENT_ATTACHED_METHOD = ComponentAttachListener.class
.getDeclaredMethod("componentAttachedToContainer",
new Class[] { ComponentAttachEvent.class });
} catch (final java.lang.NoSuchMethodException e) {
// This should never happen
throw new java.lang.RuntimeException(
"Internal error finding methods in CustomField");
}
}

public void addListener(ComponentAttachListener listener) {
addListener(ComponentContainer.ComponentAttachEvent.class, listener,
COMPONENT_ATTACHED_METHOD);
}

public void removeListener(ComponentAttachListener listener) {
removeListener(ComponentContainer.ComponentAttachEvent.class, listener,
COMPONENT_ATTACHED_METHOD);
}

public void addListener(ComponentDetachListener listener) {
// content never detached
}

public void removeListener(ComponentDetachListener listener) {
// content never detached
}

}

+ 12
- 33
src/com/vaadin/ui/DateField.java View File

@@ -48,7 +48,7 @@ import com.vaadin.terminal.gwt.client.ui.VPopupCalendar;
*/
@SuppressWarnings("serial")
@ClientWidget(VPopupCalendar.class)
public class DateField extends AbstractField implements
public class DateField extends AbstractField<Date> implements
FieldEvents.BlurNotifier, FieldEvents.FocusNotifier {

/* Private members */
@@ -228,7 +228,7 @@ public class DateField extends AbstractField implements

// Gets the calendar
final Calendar calendar = getCalendar();
final Date currentDate = (Date) getValue();
final Date currentDate = getValue();

for (int r = resolution; r <= largestModifiable; r++) {
switch (r) {
@@ -298,10 +298,10 @@ public class DateField extends AbstractField implements
|| variables.containsKey("min")
|| variables.containsKey("sec")
|| variables.containsKey("msec") || variables
.containsKey("dateString"))) {
.containsKey("dateString"))) {

// Old and new dates
final Date oldDate = (Date) getValue();
final Date oldDate = getValue();
Date newDate = null;

// this enables analyzing invalid input on the server
@@ -469,7 +469,7 @@ public class DateField extends AbstractField implements
* the default documentation from implemented interface.
*/
@Override
public Class<?> getType() {
public Class<Date> getType() {
return Date.class;
}

@@ -479,7 +479,7 @@ public class DateField extends AbstractField implements
* @see com.vaadin.ui.AbstractField#setValue(java.lang.Object, boolean)
*/
@Override
protected void setValue(Object newValue, boolean repaintIsNotNeeded)
protected void setValue(Date newValue, boolean repaintIsNotNeeded)
throws Property.ReadOnlyException, Property.ConversionException {

/*
@@ -544,7 +544,7 @@ public class DateField extends AbstractField implements
Form f = (Form) parenOfDateField;
Collection<?> visibleItemProperties = f.getItemPropertyIds();
for (Object fieldId : visibleItemProperties) {
Field field = f.getField(fieldId);
Field<?> field = f.getField(fieldId);
if (field == this) {
/*
* this datefield is logically in a form. Do the same
@@ -564,24 +564,8 @@ public class DateField extends AbstractField implements
}
}

/**
* Sets the DateField datasource. Datasource type must assignable to Date.
*
* @see com.vaadin.data.Property.Viewer#setPropertyDataSource(Property)
*/
@Override
public void setPropertyDataSource(Property newDataSource) {
if (newDataSource == null
|| Date.class.isAssignableFrom(newDataSource.getType())) {
super.setPropertyDataSource(newDataSource);
} else {
throw new IllegalArgumentException(
"DateField only supports Date properties");
}
}

@Override
protected void setInternalValue(Object newValue) {
protected void setInternalValue(Date newValue) {
// Also set the internal dateString
if (newValue != null) {
dateString = newValue.toString();
@@ -642,7 +626,7 @@ public class DateField extends AbstractField implements
final Calendar newCal = (Calendar) calendar.clone();

// Assigns the current time tom calendar.
final Date currentDate = (Date) getValue();
final Date currentDate = getValue();
if (currentDate != null) {
newCal.setTime(currentDate);
}
@@ -752,18 +736,13 @@ public class DateField extends AbstractField implements
}

/**
* Tests the current value against registered validators if the field is not
* empty. Note that DateField is considered empty (value == null) and
* Validates the current value against registered validators if the field is
* not empty. Note that DateField is considered empty (value == null) and
* invalid if it contains text typed in by the user that couldn't be parsed
* into a Date value.
*
* @see com.vaadin.ui.AbstractField#isValid()
* @see com.vaadin.ui.AbstractField#validate()
*/
@Override
public boolean isValid() {
return uiHasValidDateString && super.isValid();
}

@Override
public void validate() throws InvalidValueException {
/*

+ 7
- 6
src/com/vaadin/ui/DefaultFieldFactory.java View File

@@ -35,19 +35,20 @@ public class DefaultFieldFactory implements FormFieldFactory, TableFieldFactory
protected DefaultFieldFactory() {
}

public Field createField(Item item, Object propertyId, Component uiContext) {
public Field<?> createField(Item item, Object propertyId,
Component uiContext) {
Class<?> type = item.getItemProperty(propertyId).getType();
Field field = createFieldByPropertyType(type);
Field<?> field = createFieldByPropertyType(type);
field.setCaption(createCaptionByPropertyId(propertyId));
return field;
}

public Field createField(Container container, Object itemId,
public Field<?> createField(Container container, Object itemId,
Object propertyId, Component uiContext) {
Property containerProperty = container.getContainerProperty(itemId,
Property<?> containerProperty = container.getContainerProperty(itemId,
propertyId);
Class<?> type = containerProperty.getType();
Field field = createFieldByPropertyType(type);
Field<?> field = createFieldByPropertyType(type);
field.setCaption(createCaptionByPropertyId(propertyId));
return field;
}
@@ -110,7 +111,7 @@ public class DefaultFieldFactory implements FormFieldFactory, TableFieldFactory
* the type of the property
* @return the most suitable generic {@link Field} for given type
*/
public static Field createFieldByPropertyType(Class<?> type) {
public static Field<?> createFieldByPropertyType(Class<?> type) {
// Null typed properties can not be edited
if (type == null) {
return null;

+ 8
- 19
src/com/vaadin/ui/Field.java View File

@@ -9,29 +9,18 @@ import com.vaadin.data.Property;
import com.vaadin.ui.Component.Focusable;

/**
* @author IT Mill Ltd.
* TODO document
*
* @param T
* the type of values in the field, which might not be the same type
* as that of the data source if converters are used
*
* @author IT Mill Ltd.
*/
public interface Field extends Component, BufferedValidatable, Property,
public interface Field<T> extends Component, BufferedValidatable, Property<T>,
Property.ValueChangeNotifier, Property.ValueChangeListener,
Property.Editor, Focusable {

/**
* Sets the Caption.
*
* @param caption
*/
void setCaption(String caption);

String getDescription();

/**
* Sets the Description.
*
* @param caption
*/
void setDescription(String caption);

/**
* Is this field required.
*
@@ -80,7 +69,7 @@ public interface Field extends Component, BufferedValidatable, Property,
* @since 3.0
*/
@SuppressWarnings("serial")
public class ValueChangeEvent extends Component.Event implements
public static class ValueChangeEvent extends Component.Event implements
Property.ValueChangeEvent {

/**

+ 2
- 2
src/com/vaadin/ui/FieldFactory.java View File

@@ -30,7 +30,7 @@ public interface FieldFactory extends FormFieldFactory, TableFieldFactory {
* @return Field the field suitable for editing the specified data.
*
*/
Field createField(Class<?> type, Component uiContext);
Field<?> createField(Class<?> type, Component uiContext);

/**
* Creates a field based on the property datasource.
@@ -41,6 +41,6 @@ public interface FieldFactory extends FormFieldFactory, TableFieldFactory {
* the component where the field is presented.
* @return Field the field suitable for editing the specified data.
*/
Field createField(Property property, Component uiContext);
Field<?> createField(Property property, Component uiContext);

}

+ 29
- 43
src/com/vaadin/ui/Form.java View File

@@ -61,8 +61,8 @@ import com.vaadin.terminal.gwt.client.ui.VForm;
*/
@SuppressWarnings("serial")
@ClientWidget(VForm.class)
public class Form extends AbstractField implements Item.Editor, Buffered, Item,
Validatable, Action.Notifier {
public class Form extends AbstractField<Object> implements Item.Editor,
Buffered, Item, Validatable, Action.Notifier {

private Object propertyValue;

@@ -99,12 +99,12 @@ public class Form extends AbstractField implements Item.Editor, Buffered, Item,
/**
* Mapping from propertyName to corresponding field.
*/
private final HashMap<Object, Field> fields = new HashMap<Object, Field>();
private final HashMap<Object, Field<?>> fields = new HashMap<Object, Field<?>>();

/**
* Form may act as an Item, its own properties are stored here.
*/
private final HashMap<Object, Property> ownProperties = new HashMap<Object, Property>();
private final HashMap<Object, Property<?>> ownProperties = new HashMap<Object, Property<?>>();

/**
* Field factory for this form.
@@ -242,7 +242,7 @@ public class Form extends AbstractField implements Item.Editor, Buffered, Item,
field.getCaption());
}
break;
} else if (f instanceof Field && !((Field) f).isValid()) {
} else if (f instanceof Field && !((Field<?>) f).isValid()) {
// Something is wrong with the field, but no proper
// error is given. Generate one.
validationError = new Validator.InvalidValueException(
@@ -321,7 +321,7 @@ public class Form extends AbstractField implements Item.Editor, Buffered, Item,
// Try to commit all
for (final Iterator<Object> i = propertyIds.iterator(); i.hasNext();) {
try {
final Field f = (fields.get(i.next()));
final Field<?> f = (fields.get(i.next()));
// Commit only non-readonly fields.
if (!f.isReadOnly()) {
f.commit();
@@ -408,7 +408,7 @@ public class Form extends AbstractField implements Item.Editor, Buffered, Item,
@Override
public boolean isModified() {
for (final Iterator<Object> i = propertyIds.iterator(); i.hasNext();) {
final Field f = fields.get(i.next());
final Field<?> f = fields.get(i.next());
if (f != null && f.isModified()) {
return true;
}
@@ -485,7 +485,7 @@ public class Form extends AbstractField implements Item.Editor, Buffered, Item,
ownProperties.put(id, property);

// Gets suitable field
final Field field = fieldFactory.createField(this, id, this);
final Field<?> field = fieldFactory.createField(this, id, this);
if (field == null) {
return false;
}
@@ -516,7 +516,7 @@ public class Form extends AbstractField implements Item.Editor, Buffered, Item,
* @param field
* the field which should be added to the form.
*/
public void addField(Object propertyId, Field field) {
public void addField(Object propertyId, Field<?> field) {
registerField(propertyId, field);
attachField(propertyId, field);
requestRepaint();
@@ -536,7 +536,7 @@ public class Form extends AbstractField implements Item.Editor, Buffered, Item,
* @param field
* the Field that should be registered
*/
private void registerField(Object propertyId, Field field) {
private void registerField(Object propertyId, Field<?> field) {
if (propertyId == null || field == null) {
return;
}
@@ -599,13 +599,13 @@ public class Form extends AbstractField implements Item.Editor, Buffered, Item,
*
* @see com.vaadin.data.Item#getItemProperty(Object)
*/
public Property getItemProperty(Object id) {
final Field field = fields.get(id);
public Property<?> getItemProperty(Object id) {
final Field<?> field = fields.get(id);
if (field == null) {
// field does not exist or it is not (yet) created for this property
return ownProperties.get(id);
}
final Property property = field.getPropertyDataSource();
final Property<?> property = field.getPropertyDataSource();

if (property != null) {
return property;
@@ -620,7 +620,7 @@ public class Form extends AbstractField implements Item.Editor, Buffered, Item,
* @param propertyId
* the id of the property.
*/
public Field getField(Object propertyId) {
public Field<?> getField(Object propertyId) {
return fields.get(propertyId);
}

@@ -637,7 +637,7 @@ public class Form extends AbstractField implements Item.Editor, Buffered, Item,
public boolean removeItemProperty(Object id) {
ownProperties.remove(id);

final Field field = fields.get(id);
final Field<?> field = fields.get(id);

if (field != null) {
propertyIds.remove(id);
@@ -750,9 +750,9 @@ public class Form extends AbstractField implements Item.Editor, Buffered, Item,
// Adds all the properties to this form
for (final Iterator<?> i = propertyIds.iterator(); i.hasNext();) {
final Object id = i.next();
final Property property = itemDatasource.getItemProperty(id);
final Property<?> property = itemDatasource.getItemProperty(id);
if (id != null && property != null) {
final Field f = fieldFactory.createField(itemDatasource, id,
final Field<?> f = fieldFactory.createField(itemDatasource, id,
this);
if (f != null) {
bindPropertyToField(id, property, f);
@@ -828,7 +828,7 @@ public class Form extends AbstractField implements Item.Editor, Buffered, Item,
if (layout != null) {
final Object[] properties = propertyIds.toArray();
for (int i = 0; i < properties.length; i++) {
Field f = getField(properties[i]);
Field<?> f = getField(properties[i]);
detachField(f);
if (newLayout instanceof CustomLayout) {
((CustomLayout) newLayout).addComponent(f,
@@ -875,7 +875,7 @@ public class Form extends AbstractField implements Item.Editor, Buffered, Item,
}

// Gets the old field
final Field oldField = fields.get(propertyId);
final Field<?> oldField = fields.get(propertyId);
if (oldField == null) {
throw new IllegalArgumentException("Field with given propertyid '"
+ propertyId.toString() + "' can not be found.");
@@ -952,7 +952,7 @@ public class Form extends AbstractField implements Item.Editor, Buffered, Item,
}

// Sets the property data source
final Property property = oldField.getPropertyDataSource();
final Property<?> property = oldField.getPropertyDataSource();
oldField.setPropertyDataSource(null);
newField.setPropertyDataSource(property);

@@ -994,21 +994,7 @@ public class Form extends AbstractField implements Item.Editor, Buffered, Item,
}

/**
* Tests the current value of the object against all registered validators
*
* @see com.vaadin.data.Validatable#isValid()
*/
@Override
public boolean isValid() {
boolean valid = true;
for (final Iterator<Object> i = propertyIds.iterator(); i.hasNext();) {
valid &= (fields.get(i.next())).isValid();
}
return valid && super.isValid();
}

/**
* Checks the validity of the validatable.
* Checks the validity of the Form and all of its fields.
*
* @see com.vaadin.data.Validatable#validate()
*/
@@ -1155,11 +1141,11 @@ public class Form extends AbstractField implements Item.Editor, Buffered, Item,
*
* @return the Field.
*/
private Field getFirstFocusableField() {
private Field<?> getFirstFocusableField() {
if (getItemPropertyIds() != null) {
for (Object id : getItemPropertyIds()) {
if (id != null) {
Field field = getField(id);
Field<?> field = getField(id);
if (field.isEnabled() && !field.isReadOnly()) {
return field;
}
@@ -1248,7 +1234,7 @@ public class Form extends AbstractField implements Item.Editor, Buffered, Item,
*/
@Override
public void focus() {
final Field f = getFirstFocusableField();
final Field<?> f = getFirstFocusableField();
if (f != null) {
f.focus();
}
@@ -1274,8 +1260,8 @@ public class Form extends AbstractField implements Item.Editor, Buffered, Item,
@Override
public void setImmediate(boolean immediate) {
super.setImmediate(immediate);
for (Iterator<Field> i = fields.values().iterator(); i.hasNext();) {
Field f = i.next();
for (Iterator<Field<?>> i = fields.values().iterator(); i.hasNext();) {
Field<?> f = i.next();
if (f instanceof AbstractComponent) {
((AbstractComponent) f).setImmediate(immediate);
}
@@ -1286,10 +1272,10 @@ public class Form extends AbstractField implements Item.Editor, Buffered, Item,
@Override
protected boolean isEmpty() {

for (Iterator<Field> i = fields.values().iterator(); i.hasNext();) {
Field f = i.next();
for (Iterator<Field<?>> i = fields.values().iterator(); i.hasNext();) {
Field<?> f = i.next();
if (f instanceof AbstractField) {
if (!((AbstractField) f).isEmpty()) {
if (!((AbstractField<?>) f).isEmpty()) {
return false;
}
}

+ 1
- 1
src/com/vaadin/ui/FormFieldFactory.java View File

@@ -37,5 +37,5 @@ public interface FormFieldFactory extends Serializable {
* creating it.
* @return Field the field suitable for editing the specified data.
*/
Field createField(Item item, Object propertyId, Component uiContext);
Field<?> createField(Item item, Object propertyId, Component uiContext);
}

+ 34
- 11
src/com/vaadin/ui/Label.java View File

@@ -40,6 +40,7 @@ import com.vaadin.ui.ClientWidget.LoadStyle;
*/
@SuppressWarnings("serial")
@ClientWidget(value = VLabel.class, loadStyle = LoadStyle.EAGER)
// TODO generics for interface Property
public class Label extends AbstractComponent implements Property,
Property.Viewer, Property.ValueChangeListener,
Property.ValueChangeNotifier, Comparable<Object> {
@@ -194,24 +195,24 @@ public class Label extends AbstractComponent implements Property,
target.addAttribute("mode", CONTENT_MODE_NAME[contentMode]);
}
if (contentMode == CONTENT_TEXT) {
target.addText(toString());
target.addText(getStringValue());
} else if (contentMode == CONTENT_UIDL) {
target.addUIDL(toString());
target.addUIDL(getStringValue());
} else if (contentMode == CONTENT_XHTML) {
target.startTag("data");
target.addXMLSection("div", toString(),
target.addXMLSection("div", getStringValue(),
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd");
target.endTag("data");
} else if (contentMode == CONTENT_PREFORMATTED) {
target.startTag("pre");
target.addText(toString());
target.addText(getStringValue());
target.endTag("pre");
} else if (contentMode == CONTENT_XML) {
target.addXMLSection("data", toString(), null);
target.addXMLSection("data", getStringValue(), null);
} else if (contentMode == CONTENT_RAW) {
target.startTag("data");
target.addAttribute("escape", false);
target.addText(toString());
target.addText(getStringValue());
target.endTag("data");
}

@@ -246,13 +247,33 @@ public class Label extends AbstractComponent implements Property,

/**
* @see java.lang.Object#toString()
* @deprecated use the data source value or {@link #getStringValue()}
* instead
*/
@Deprecated
@Override
public String toString() {
throw new UnsupportedOperationException(
"Use Property.getValue() instead of Label.toString()");
}

/**
* Returns the value of the <code>Property</code> in human readable textual
* format.
*
* This method exists to help migration from previous Vaadin versions by
* providing a simple replacement for {@link #toString()}. However, it is
* normally better to use the value of the label directly.
*
* @return String representation of the value stored in the Property
* @since 7.0
*/
public String getStringValue() {
if (dataSource == null) {
throw new IllegalStateException(DATASOURCE_MUST_BE_SET);
}
return dataSource.toString();
Object value = dataSource.getValue();
return (null != value) ? value.toString() : null;
}

/**
@@ -397,7 +418,7 @@ public class Label extends AbstractComponent implements Property,
* @VERSION@
* @since 3.0
*/
public class ValueChangeEvent extends Component.Event implements
public static class ValueChangeEvent extends Component.Event implements
Property.ValueChangeEvent {

/**
@@ -489,17 +510,19 @@ public class Label extends AbstractComponent implements Property,

if (contentMode == CONTENT_XML || contentMode == CONTENT_UIDL
|| contentMode == CONTENT_XHTML) {
thisValue = stripTags(toString());
thisValue = stripTags(getStringValue());
} else {
thisValue = toString();
thisValue = getStringValue();
}

if (other instanceof Label
&& (((Label) other).getContentMode() == CONTENT_XML
|| ((Label) other).getContentMode() == CONTENT_UIDL || ((Label) other)
.getContentMode() == CONTENT_XHTML)) {
otherValue = stripTags(other.toString());
otherValue = stripTags(((Label) other).getStringValue());
} else {
// TODO not a good idea - and might assume that Field.toString()
// returns a string representation of the value
otherValue = other.toString();
}


+ 0
- 4
src/com/vaadin/ui/NativeButton.java View File

@@ -21,8 +21,4 @@ public class NativeButton extends Button {
super(caption, listener);
}

public NativeButton(String caption, Object target, String methodName) {
super(caption, target, methodName);
}

}

+ 10
- 9
src/com/vaadin/ui/ProgressIndicator.java View File

@@ -26,7 +26,7 @@ import com.vaadin.terminal.gwt.client.ui.VProgressIndicator;
*/
@SuppressWarnings("serial")
@ClientWidget(VProgressIndicator.class)
public class ProgressIndicator extends AbstractField implements Property,
public class ProgressIndicator extends AbstractField<Number> implements
Property.Viewer, Property.ValueChangeListener {

/**
@@ -125,11 +125,12 @@ public class ProgressIndicator extends AbstractField implements Property,
* @see com.vaadin.ui.AbstractField#getValue()
*/
@Override
public Object getValue() {
public Number getValue() {
if (dataSource == null) {
throw new IllegalStateException("Datasource must be set");
}
return dataSource.getValue();
// TODO conversions to eliminate cast
return (Number) dataSource.getValue();
}

/**
@@ -138,7 +139,7 @@ public class ProgressIndicator extends AbstractField implements Property,
*
* @param newValue
* the New value of the ProgressIndicator.
* @see com.vaadin.ui.AbstractField#setValue(java.lang.Object)
* @see com.vaadin.ui.AbstractField#setValue()
*/
@Override
public void setValue(Object newValue) {
@@ -150,20 +151,20 @@ public class ProgressIndicator extends AbstractField implements Property,

/**
* @see com.vaadin.ui.AbstractField#toString()
* @deprecated use the data source value instead of toString()
*/
@Deprecated
@Override
public String toString() {
if (dataSource == null) {
throw new IllegalStateException("Datasource must be set");
}
return dataSource.toString();
throw new UnsupportedOperationException(
"Use Property.getValue() instead of ProgressIndicator.toString()");
}

/**
* @see com.vaadin.ui.AbstractField#getType()
*/
@Override
public Class<?> getType() {
public Class<? extends Number> getType() {
if (dataSource == null) {
throw new IllegalStateException("Datasource must be set");
}

+ 5
- 5
src/com/vaadin/ui/RichTextArea.java View File

@@ -21,7 +21,7 @@ import com.vaadin.ui.ClientWidget.LoadStyle;
* into length of field.
*/
@ClientWidget(value = VRichTextArea.class, loadStyle = LoadStyle.LAZY)
public class RichTextArea extends AbstractField {
public class RichTextArea extends AbstractField<String> {

/**
* Value formatter used to format the string contents.
@@ -176,8 +176,8 @@ public class RichTextArea extends AbstractField {
}

@Override
public Object getValue() {
Object v = super.getValue();
public String getValue() {
String v = super.getValue();
if (format == null || v == null) {
return v;
}
@@ -222,7 +222,7 @@ public class RichTextArea extends AbstractField {
}

@Override
public Class getType() {
public Class<String> getType() {
return String.class;
}

@@ -343,7 +343,7 @@ public class RichTextArea extends AbstractField {

@Override
protected boolean isEmpty() {
return super.isEmpty() || toString().length() == 0;
return super.isEmpty() || getStringValue().length() == 0;
}

}

+ 4
- 5
src/com/vaadin/ui/Slider.java View File

@@ -48,7 +48,7 @@ import com.vaadin.terminal.gwt.client.ui.VSlider;
*/
@SuppressWarnings("serial")
@ClientWidget(VSlider.class)
public class Slider extends AbstractField {
public class Slider extends AbstractField<Number> {

public static final int ORIENTATION_HORIZONTAL = 0;

@@ -408,10 +408,9 @@ public class Slider extends AbstractField {
target.addAttribute("resolution", resolution);

if (resolution > 0) {
target.addVariable(this, "value",
((Double) getValue()).doubleValue());
target.addVariable(this, "value", getValue().doubleValue());
} else {
target.addVariable(this, "value", ((Double) getValue()).intValue());
target.addVariable(this, "value", getValue().intValue());
}

if (orientation == ORIENTATION_VERTICAL) {
@@ -493,7 +492,7 @@ public class Slider extends AbstractField {
}

@Override
public Class getType() {
public Class<Double> getType() {
return Double.class;
}


+ 67
- 18
src/com/vaadin/ui/Table.java View File

@@ -20,11 +20,13 @@ import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.vaadin.Application;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.util.ContainerOrderedWrapper;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.event.Action;
import com.vaadin.event.Action.Handler;
import com.vaadin.event.DataBoundTransferable;
@@ -70,7 +72,7 @@ import com.vaadin.terminal.gwt.client.ui.dd.VLazyInitItemIdentifiers;
* @VERSION@
* @since 3.0
*/
@SuppressWarnings({ "serial", "deprecation" })
@SuppressWarnings({ "deprecation" })
@ClientWidget(VScrollTable.class)
public class Table extends AbstractSelect implements Action.Container,
Container.Ordered, Container.Sortable, ItemClickSource,
@@ -309,7 +311,7 @@ public class Table extends AbstractSelect implements Action.Container,
* Set of properties listened - the list is kept to release the listeners
* later.
*/
private HashSet<Property> listenedProperties = null;
private HashSet<Property<?>> listenedProperties = null;

/**
* Set of visible components - the is used for needsRepaint calculation.
@@ -404,10 +406,12 @@ public class Table extends AbstractSelect implements Action.Container,

private RowGenerator rowGenerator = null;

private final Map<Field, Property> associatedProperties = new HashMap<Field, Property>();
private final Map<Field<?>, Property<?>> associatedProperties = new HashMap<Field<?>, Property<?>>();

private boolean painted = false;

private HashMap<Object, Converter> propertyValueConverters = new HashMap<Object, Converter>();

/* Table constructors */

/**
@@ -1718,13 +1722,13 @@ public class Table extends AbstractSelect implements Action.Container,
final Object[] colids = getVisibleColumns();
final int cols = colids.length;

HashSet<Property> oldListenedProperties = listenedProperties;
HashSet<Property<?>> oldListenedProperties = listenedProperties;
HashSet<Component> oldVisibleComponents = visibleComponents;

if (replaceListeners) {
// initialize the listener collections, this should only be done if
// the entire cache is refreshed (through refreshRenderedCells)
listenedProperties = new HashSet<Property>();
listenedProperties = new HashSet<Property<?>>();
visibleComponents = new HashSet<Component>();
}

@@ -1784,7 +1788,7 @@ public class Table extends AbstractSelect implements Action.Container,
if (isColumnCollapsed(colids[j])) {
continue;
}
Property p = null;
Property<?> p = null;
Object value = "";
boolean isGeneratedRow = generatedRow != null;
boolean isGeneratedColumn = columnGenerators
@@ -1904,8 +1908,8 @@ public class Table extends AbstractSelect implements Action.Container,
visibleComponents.add(component);
}

private void listenProperty(Property p,
HashSet<Property> oldListenedProperties) {
private void listenProperty(Property<?> p,
HashSet<Property<?>> oldListenedProperties) {
if (p instanceof Property.ValueChangeNotifier) {
if (oldListenedProperties == null
|| !oldListenedProperties.contains(p)) {
@@ -1945,7 +1949,7 @@ public class Table extends AbstractSelect implements Action.Container,
visibleComponents.remove(cellVal);
unregisterComponent((Component) cellVal);
} else {
Property p = getContainerProperty(
Property<?> p = getContainerProperty(
pageBuffer[CELL_ITEMID][i + ix], colids[c]);
if (p instanceof ValueChangeNotifier
&& listenedProperties.contains(p)) {
@@ -1970,7 +1974,7 @@ public class Table extends AbstractSelect implements Action.Container,
* set of components that where attached in last render
*/
private void unregisterPropertiesAndComponents(
HashSet<Property> oldListenedProperties,
HashSet<Property<?>> oldListenedProperties,
HashSet<Component> oldVisibleComponents) {
if (oldVisibleComponents != null) {
for (final Iterator<Component> i = oldVisibleComponents.iterator(); i
@@ -1983,8 +1987,8 @@ public class Table extends AbstractSelect implements Action.Container,
}

if (oldListenedProperties != null) {
for (final Iterator<Property> i = oldListenedProperties.iterator(); i
.hasNext();) {
for (final Iterator<Property<?>> i = oldListenedProperties
.iterator(); i.hasNext();) {
Property.ValueChangeNotifier o = (ValueChangeNotifier) i.next();
if (!listenedProperties.contains(o)) {
o.removeListener(this);
@@ -2017,8 +2021,8 @@ public class Table extends AbstractSelect implements Action.Container,
* fields in memory.
*/
if (component instanceof Field) {
Field field = (Field) component;
Property associatedProperty = associatedProperties
Field<?> field = (Field<?>) component;
Property<?> associatedProperty = associatedProperties
.remove(component);
if (associatedProperty != null
&& field.getPropertyDataSource() == associatedProperty) {
@@ -3399,8 +3403,8 @@ public class Table extends AbstractSelect implements Action.Container,
protected Object getPropertyValue(Object rowId, Object colId,
Property property) {
if (isEditable() && fieldFactory != null) {
final Field f = fieldFactory.createField(getContainerDataSource(),
rowId, colId, this);
final Field<?> f = fieldFactory.createField(
getContainerDataSource(), rowId, colId, this);
if (f != null) {
// Remember that we have made this association so we can remove
// it when the component is removed
@@ -3454,11 +3458,25 @@ public class Table extends AbstractSelect implements Action.Container,
* @since 3.1
*/
protected String formatPropertyValue(Object rowId, Object colId,
Property property) {
Property<?> property) {
if (property == null) {
return "";
}
return property.toString();
Converter<Object, String> converter = null;

if (hasConverter(colId)) {
converter = getConverter(colId);
} else {
// FIXME: Use thread local
converter = (Converter<Object, String>) Application
.getConverterFactory().createConverter(property.getType(),
String.class);
}
Object value = property.getValue();
if (converter != null) {
return converter.convertFromSourceToTarget(value, getLocale());
}
return (null != value) ? value.toString() : "";
}

/* Action container */
@@ -5141,4 +5159,35 @@ public class Table extends AbstractSelect implements Action.Container,
public RowGenerator getRowGenerator() {
return rowGenerator;
}

// FIXME: Javadoc
public void setConverter(Object propertyId, Converter<?, String> converter) {
if (!getContainerPropertyIds().contains(propertyId)) {
throw new IllegalArgumentException("PropertyId " + propertyId
+ " must be in the container");
}
// FIXME: This check should be here but primitive types like Boolean
// formatter for boolean property must be handled

// if (!converter.getSourceType().isAssignableFrom(getType(propertyId)))
// {
// throw new IllegalArgumentException("Property type ("
// + getType(propertyId)
// + ") must match converter source type ("
// + converter.getSourceType() + ")");
// }
propertyValueConverters.put(propertyId, converter);
refreshRowCache();
}

// FIXME: Javadoc
protected boolean hasConverter(Object propertyId) {
return propertyValueConverters.containsKey(propertyId);
}

// FIXME: Javadoc
public Converter<Object, String> getConverter(Object propertyId) {
return propertyValueConverters.get(propertyId);
}

}

+ 1
- 1
src/com/vaadin/ui/TableFieldFactory.java View File

@@ -39,7 +39,7 @@ public interface TableFieldFactory extends Serializable {
* @return A field suitable for editing the specified data or null if the
* property should not be editable.
*/
Field createField(Container container, Object itemId, Object propertyId,
Field<?> createField(Container container, Object itemId, Object propertyId,
Component uiContext);

}

+ 1
- 6
tests/server-side/com/vaadin/data/util/BeanItemTest.java View File

@@ -12,11 +12,6 @@ import java.util.Map;
import junit.framework.Assert;
import junit.framework.TestCase;

import com.vaadin.data.util.BeanItem;
import com.vaadin.data.util.MethodProperty;
import com.vaadin.data.util.MethodPropertyDescriptor;
import com.vaadin.data.util.VaadinPropertyDescriptor;

/**
* Test BeanItem specific features.
*
@@ -322,7 +317,7 @@ public class BeanItemTest extends TestCase {
MyClass.class.getDeclaredMethod("getName"),
MyClass.class.getDeclaredMethod("setName", String.class));

BeanItem<MyClass> item = new BeanItem(new MyClass("bean1"));
BeanItem<MyClass> item = new BeanItem<MyClass>(new MyClass("bean1"));

Assert.assertEquals(6, item.getItemPropertyIds().size());
Assert.assertEquals(null, item.getItemProperty("myname"));

+ 45
- 44
tests/server-side/com/vaadin/data/util/NestedMethodPropertyTest.java View File

@@ -10,8 +10,6 @@ import java.io.Serializable;
import junit.framework.Assert;
import junit.framework.TestCase;

import com.vaadin.data.util.NestedMethodProperty;

public class NestedMethodPropertyTest extends TestCase {

public static class Address implements Serializable {
@@ -126,34 +124,34 @@ public class NestedMethodPropertyTest extends TestCase {
}

public void testSingleLevelNestedSimpleProperty() {
NestedMethodProperty nameProperty = new NestedMethodProperty(vaadin,
"name");
NestedMethodProperty<String> nameProperty = new NestedMethodProperty<String>(
vaadin, "name");

Assert.assertEquals(String.class, nameProperty.getType());
Assert.assertEquals("Vaadin", nameProperty.getValue());
}

public void testSingleLevelNestedObjectProperty() {
NestedMethodProperty managerProperty = new NestedMethodProperty(vaadin,
"manager");
NestedMethodProperty<Person> managerProperty = new NestedMethodProperty<Person>(
vaadin, "manager");

Assert.assertEquals(Person.class, managerProperty.getType());
Assert.assertEquals(joonas, managerProperty.getValue());
}

public void testMultiLevelNestedProperty() {
NestedMethodProperty managerNameProperty = new NestedMethodProperty(
NestedMethodProperty<String> managerNameProperty = new NestedMethodProperty<String>(
vaadin, "manager.name");
NestedMethodProperty addressProperty = new NestedMethodProperty(vaadin,
"manager.address");
NestedMethodProperty streetProperty = new NestedMethodProperty(vaadin,
"manager.address.street");
NestedMethodProperty postalCodePrimitiveProperty = new NestedMethodProperty(
NestedMethodProperty<Address> addressProperty = new NestedMethodProperty<Address>(
vaadin, "manager.address");
NestedMethodProperty<String> streetProperty = new NestedMethodProperty<String>(
vaadin, "manager.address.street");
NestedMethodProperty<Integer> postalCodePrimitiveProperty = new NestedMethodProperty<Integer>(
vaadin, "manager.address.postalCodePrimitive");
NestedMethodProperty postalCodeObjectProperty = new NestedMethodProperty(
NestedMethodProperty<Integer> postalCodeObjectProperty = new NestedMethodProperty<Integer>(
vaadin, "manager.address.postalCodeObject");
NestedMethodProperty booleanProperty = new NestedMethodProperty(vaadin,
"manager.address.boolean");
NestedMethodProperty<Boolean> booleanProperty = new NestedMethodProperty<Boolean>(
vaadin, "manager.address.boolean");

Assert.assertEquals(String.class, managerNameProperty.getType());
Assert.assertEquals("Joonas", managerNameProperty.getValue());
@@ -166,25 +164,27 @@ public class NestedMethodPropertyTest extends TestCase {

Assert.assertEquals(Integer.class,
postalCodePrimitiveProperty.getType());
Assert.assertEquals(20540, postalCodePrimitiveProperty.getValue());
Assert.assertEquals(Integer.valueOf(20540),
postalCodePrimitiveProperty.getValue());

Assert.assertEquals(Integer.class, postalCodeObjectProperty.getType());
Assert.assertEquals(20540, postalCodeObjectProperty.getValue());
Assert.assertEquals(Integer.valueOf(20540),
postalCodeObjectProperty.getValue());

Assert.assertEquals(Boolean.class, booleanProperty.getType());
Assert.assertEquals(true, booleanProperty.getValue());
Assert.assertEquals(Boolean.TRUE, booleanProperty.getValue());
}

public void testEmptyPropertyName() {
try {
new NestedMethodProperty(vaadin, "");
new NestedMethodProperty<Object>(vaadin, "");
fail();
} catch (IllegalArgumentException e) {
// should get exception
}

try {
new NestedMethodProperty(vaadin, " ");
new NestedMethodProperty<Object>(vaadin, " ");
fail();
} catch (IllegalArgumentException e) {
// should get exception
@@ -193,25 +193,25 @@ public class NestedMethodPropertyTest extends TestCase {

public void testInvalidPropertyName() {
try {
new NestedMethodProperty(vaadin, ".");
new NestedMethodProperty<Object>(vaadin, ".");
fail();
} catch (IllegalArgumentException e) {
// should get exception
}
try {
new NestedMethodProperty(vaadin, ".manager");
new NestedMethodProperty<Object>(vaadin, ".manager");
fail();
} catch (IllegalArgumentException e) {
// should get exception
}
try {
new NestedMethodProperty(vaadin, "manager.");
new NestedMethodProperty<Object>(vaadin, "manager.");
fail();
} catch (IllegalArgumentException e) {
// should get exception
}
try {
new NestedMethodProperty(vaadin, "manager..name");
new NestedMethodProperty<Object>(vaadin, "manager..name");
fail();
} catch (IllegalArgumentException e) {
// should get exception
@@ -220,21 +220,21 @@ public class NestedMethodPropertyTest extends TestCase {

public void testInvalidNestedPropertyName() {
try {
new NestedMethodProperty(vaadin, "member");
new NestedMethodProperty<Object>(vaadin, "member");
fail();
} catch (IllegalArgumentException e) {
// should get exception
}

try {
new NestedMethodProperty(vaadin, "manager.pet");
new NestedMethodProperty<Object>(vaadin, "manager.pet");
fail();
} catch (IllegalArgumentException e) {
// should get exception
}

try {
new NestedMethodProperty(vaadin, "manager.address.city");
new NestedMethodProperty<Object>(vaadin, "manager.address.city");
fail();
} catch (IllegalArgumentException e) {
// should get exception
@@ -242,10 +242,10 @@ public class NestedMethodPropertyTest extends TestCase {
}

public void testNullNestedProperty() {
NestedMethodProperty managerNameProperty = new NestedMethodProperty(
NestedMethodProperty<String> managerNameProperty = new NestedMethodProperty<String>(
vaadin, "manager.name");
NestedMethodProperty streetProperty = new NestedMethodProperty(vaadin,
"manager.address.street");
NestedMethodProperty<String> streetProperty = new NestedMethodProperty<String>(
vaadin, "manager.address.street");

joonas.setAddress(null);
try {
@@ -274,15 +274,15 @@ public class NestedMethodPropertyTest extends TestCase {
}

public void testMultiLevelNestedPropertySetValue() {
NestedMethodProperty managerNameProperty = new NestedMethodProperty(
NestedMethodProperty<String> managerNameProperty = new NestedMethodProperty<String>(
vaadin, "manager.name");
NestedMethodProperty addressProperty = new NestedMethodProperty(vaadin,
"manager.address");
NestedMethodProperty streetProperty = new NestedMethodProperty(vaadin,
"manager.address.street");
NestedMethodProperty postalCodePrimitiveProperty = new NestedMethodProperty(
NestedMethodProperty<Address> addressProperty = new NestedMethodProperty<Address>(
vaadin, "manager.address");
NestedMethodProperty<String> streetProperty = new NestedMethodProperty<String>(
vaadin, "manager.address.street");
NestedMethodProperty<Integer> postalCodePrimitiveProperty = new NestedMethodProperty<Integer>(
vaadin, "manager.address.postalCodePrimitive");
NestedMethodProperty postalCodeObjectProperty = new NestedMethodProperty(
NestedMethodProperty<Integer> postalCodeObjectProperty = new NestedMethodProperty<Integer>(
vaadin, "manager.address.postalCodeObject");

managerNameProperty.setValue("Joonas L");
@@ -303,21 +303,22 @@ public class NestedMethodPropertyTest extends TestCase {
}

public void testSerialization() throws IOException, ClassNotFoundException {
NestedMethodProperty streetProperty = new NestedMethodProperty(vaadin,
"manager.address.street");
NestedMethodProperty<String> streetProperty = new NestedMethodProperty<String>(
vaadin, "manager.address.street");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
new ObjectOutputStream(baos).writeObject(streetProperty);
NestedMethodProperty property2 = (NestedMethodProperty) new ObjectInputStream(
@SuppressWarnings("unchecked")
NestedMethodProperty<String> property2 = (NestedMethodProperty<String>) new ObjectInputStream(
new ByteArrayInputStream(baos.toByteArray())).readObject();

Assert.assertEquals("Ruukinkatu 2-4", property2.getValue());
}

public void testIsReadOnly() {
NestedMethodProperty streetProperty = new NestedMethodProperty(vaadin,
"manager.address.street");
NestedMethodProperty booleanProperty = new NestedMethodProperty(vaadin,
"manager.address.boolean");
NestedMethodProperty<String> streetProperty = new NestedMethodProperty<String>(
vaadin, "manager.address.street");
NestedMethodProperty<Boolean> booleanProperty = new NestedMethodProperty<Boolean>(
vaadin, "manager.address.boolean");

Assert.assertFalse(streetProperty.isReadOnly());
Assert.assertTrue(booleanProperty.isReadOnly());

+ 3
- 5
tests/server-side/com/vaadin/data/util/ObjectPropertyTest.java View File

@@ -4,8 +4,6 @@ import junit.framework.TestCase;
import org.junit.Assert;
import com.vaadin.data.util.ObjectProperty;
public class ObjectPropertyTest extends TestCase {
public static class TestSuperClass {
@@ -70,7 +68,7 @@ public class ObjectPropertyTest extends TestCase {
ObjectProperty<TestSuperClass> prop = new ObjectProperty<TestSuperClass>(
super1, TestSuperClass.class);
Assert.assertEquals("super1", prop.getValue().getName());
prop.setValue("super2");
prop.setValue(new TestSuperClass("super2"));
Assert.assertEquals("super1", super1.getName());
Assert.assertEquals("super2", prop.getValue().getName());
}
@@ -79,7 +77,7 @@ public class ObjectPropertyTest extends TestCase {
ObjectProperty<TestSubClass> prop = new ObjectProperty<TestSubClass>(
sub1, TestSubClass.class);
Assert.assertEquals("Subclass: sub1", prop.getValue().getName());
prop.setValue("sub2");
prop.setValue(new TestSubClass("sub2"));
Assert.assertEquals("Subclass: sub1", sub1.getName());
Assert.assertEquals("Subclass: sub2", prop.getValue().getName());
}
@@ -92,7 +90,7 @@ public class ObjectPropertyTest extends TestCase {
// create correct subclass based on the runtime type of the instance
// given to ObjectProperty constructor, which is a subclass of the type
// parameter
prop.setValue("sub2");
prop.setValue(new TestSubClass("sub2"));
Assert.assertEquals("Subclass: sub2", prop.getValue().getName());
}

+ 5
- 6
tests/server-side/com/vaadin/data/util/PropertyDescriptorTest.java View File

@@ -11,9 +11,6 @@ import junit.framework.Assert;
import junit.framework.TestCase;

import com.vaadin.data.Property;
import com.vaadin.data.util.MethodPropertyDescriptor;
import com.vaadin.data.util.NestedPropertyDescriptor;
import com.vaadin.data.util.VaadinPropertyDescriptor;
import com.vaadin.data.util.NestedMethodPropertyTest.Person;

public class PropertyDescriptorTest extends TestCase {
@@ -33,11 +30,12 @@ public class PropertyDescriptorTest extends TestCase {

ByteArrayOutputStream baos = new ByteArrayOutputStream();
new ObjectOutputStream(baos).writeObject(descriptor);
@SuppressWarnings("unchecked")
VaadinPropertyDescriptor<Person> descriptor2 = (VaadinPropertyDescriptor<Person>) new ObjectInputStream(
new ByteArrayInputStream(baos.toByteArray())).readObject();

Property property = descriptor2
.createProperty(new Person("John", null));
Property<?> property = descriptor2.createProperty(new Person("John",
null));
Assert.assertEquals("John", property.getValue());
}

@@ -47,10 +45,11 @@ public class PropertyDescriptorTest extends TestCase {

ByteArrayOutputStream baos = new ByteArrayOutputStream();
new ObjectOutputStream(baos).writeObject(pd);
@SuppressWarnings("unchecked")
VaadinPropertyDescriptor<Person> pd2 = (VaadinPropertyDescriptor<Person>) new ObjectInputStream(
new ByteArrayInputStream(baos.toByteArray())).readObject();

Property property = pd2.createProperty(new Person("John", null));
Property<?> property = pd2.createProperty(new Person("John", null));
Assert.assertEquals("John", property.getValue());
}
}

+ 3
- 5
tests/server-side/com/vaadin/data/util/PropertySetItemTest.java View File

@@ -9,8 +9,6 @@ import org.easymock.EasyMock;

import com.vaadin.data.Item.PropertySetChangeEvent;
import com.vaadin.data.Item.PropertySetChangeListener;
import com.vaadin.data.util.ObjectProperty;
import com.vaadin.data.util.PropertysetItem;

public class PropertySetItemTest extends TestCase {

@@ -395,13 +393,13 @@ public class PropertySetItemTest extends TestCase {

item.addItemProperty(ID1, prop1);

Assert.assertEquals(String.valueOf(prop1), item.toString());
Assert.assertEquals(String.valueOf(prop1.getValue()), item.toString());

item.addItemProperty(ID2, prop2);

Assert.assertEquals(
String.valueOf(prop1) + " " + String.valueOf(prop2),
item.toString());
String.valueOf(prop1.getValue()) + " "
+ String.valueOf(prop2.getValue()), item.toString());
}

}

+ 3
- 3
tests/server-side/com/vaadin/data/util/filter/AbstractFilterTest.java View File

@@ -22,9 +22,9 @@ public abstract class AbstractFilterTest<FILTERTYPE extends Filter> extends
}
}

protected static class NullProperty implements Property {
protected static class NullProperty implements Property<String> {

public Object getValue() {
public String getValue() {
return null;
}

@@ -33,7 +33,7 @@ public abstract class AbstractFilterTest<FILTERTYPE extends Filter> extends
throw new ReadOnlyException();
}

public Class<?> getType() {
public Class<String> getType() {
return String.class;
}


+ 1
- 3
tests/server-side/com/vaadin/data/util/filter/AndOrFilterTest.java View File

@@ -5,10 +5,8 @@ import junit.framework.Assert;
import com.vaadin.data.Container.Filter;
import com.vaadin.data.Item;
import com.vaadin.data.util.BeanItem;
import com.vaadin.data.util.filter.And;
import com.vaadin.data.util.filter.Or;

public class AndOrFilterTest extends AbstractFilterTest {
public class AndOrFilterTest extends AbstractFilterTest<AbstractJunctionFilter> {

protected Item item1 = new BeanItem<Integer>(1);
protected Item item2 = new BeanItem<Integer>(2);

+ 1
- 1
tests/server-side/com/vaadin/data/util/filter/CompareFilterTest.java View File

@@ -14,7 +14,7 @@ import com.vaadin.data.util.filter.Compare.GreaterOrEqual;
import com.vaadin.data.util.filter.Compare.Less;
import com.vaadin.data.util.filter.Compare.LessOrEqual;

public class CompareFilterTest extends AbstractFilterTest {
public class CompareFilterTest extends AbstractFilterTest<Compare> {

protected Item itemNull;
protected Item itemEmpty;

+ 1
- 3
tests/server-side/com/vaadin/data/util/filter/IsNullFilterTest.java View File

@@ -6,10 +6,8 @@ import com.vaadin.data.Container.Filter;
import com.vaadin.data.Item;
import com.vaadin.data.util.ObjectProperty;
import com.vaadin.data.util.PropertysetItem;
import com.vaadin.data.util.filter.And;
import com.vaadin.data.util.filter.IsNull;

public class IsNullFilterTest extends AbstractFilterTest {
public class IsNullFilterTest extends AbstractFilterTest<IsNull> {

public void testIsNull() {
Item item1 = new PropertysetItem();

+ 1
- 3
tests/server-side/com/vaadin/data/util/filter/NotFilterTest.java View File

@@ -5,10 +5,8 @@ import junit.framework.Assert;
import com.vaadin.data.Container.Filter;
import com.vaadin.data.Item;
import com.vaadin.data.util.BeanItem;
import com.vaadin.data.util.filter.And;
import com.vaadin.data.util.filter.Not;

public class NotFilterTest extends AbstractFilterTest {
public class NotFilterTest extends AbstractFilterTest<Not> {

protected Item item1 = new BeanItem<Integer>(1);
protected Item item2 = new BeanItem<Integer>(2);

+ 2
- 3
tests/server-side/com/vaadin/data/util/filter/SimpleStringFilterTest.java View File

@@ -2,9 +2,8 @@ package com.vaadin.data.util.filter;

import junit.framework.Assert;

import com.vaadin.data.util.filter.SimpleStringFilter;

public class SimpleStringFilterTest extends AbstractFilterTest {
public class SimpleStringFilterTest extends
AbstractFilterTest<SimpleStringFilter> {

protected static TestItem<String, String> createTestItem() {
return new TestItem<String, String>("abcde", "TeSt");

+ 1
- 1
tests/server-side/com/vaadin/data/util/sqlcontainer/SQLContainerTest.java View File

@@ -1344,7 +1344,7 @@ public class SQLContainerTest {
Statement statement = conn.createStatement();
statement
.executeUpdate("DELETE FROM people WHERE \"ID\"="
+ item.getItemProperty("ID"));
+ item.getItemProperty("ID").getValue());
statement.close();
return true;
}

+ 1
- 1
tests/server-side/com/vaadin/data/util/sqlcontainer/filters/BetweenTest.java View File

@@ -12,7 +12,7 @@ import com.vaadin.data.util.filter.Between;
public class BetweenTest {

private Item itemWithPropertyValue(Object propertyId, Object value) {
Property property = EasyMock.createMock(Property.class);
Property<?> property = EasyMock.createMock(Property.class);
property.getValue();
EasyMock.expectLastCall().andReturn(value).anyTimes();
EasyMock.replay(property);

+ 63
- 0
tests/server-side/com/vaadin/tests/data/bean/Address.java View File

@@ -0,0 +1,63 @@
package com.vaadin.tests.data.bean;
import java.io.Serializable;
@SuppressWarnings("serial")
public class Address implements Serializable {
private String streetAddress = "";
private Integer postalCode = null;
private String city = "";
private Country country = null;
public Address() {
}
public Address(String streetAddress, int postalCode, String city,
Country country) {
setStreetAddress(streetAddress);
setPostalCode(postalCode);
setCity(city);
setCountry(country);
}
@Override
public String toString() {
return "Address [streetAddress=" + streetAddress + ", postalCode="
+ postalCode + ", city=" + city + ", country=" + country + "]";
}
public String getStreetAddress() {
return streetAddress;
}
public void setStreetAddress(String streetAddress) {
this.streetAddress = streetAddress;
}
public Integer getPostalCode() {
return postalCode;
}
public void setPostalCode(Integer postalCode) {
this.postalCode = postalCode;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public Country getCountry() {
return country;
}
public void setCountry(Country country) {
this.country = country;
}
}

+ 18
- 0
tests/server-side/com/vaadin/tests/data/bean/Country.java View File

@@ -0,0 +1,18 @@
package com.vaadin.tests.data.bean;
public enum Country {
FINLAND("Finland"), SWEDEN("Sweden"), USA("USA"), RUSSIA("Russia"), NETHERLANDS(
"Netherlands"), SOUTH_AFRICA("South Africa");
private String name;
private Country(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}

+ 133
- 0
tests/server-side/com/vaadin/tests/data/bean/Person.java View File

@@ -0,0 +1,133 @@
package com.vaadin.tests.data.bean;
import java.math.BigDecimal;
import java.util.Date;
public class Person {
private String firstName;
private String lastName;
private String email;
private int age;
private Sex sex;
private Address address;
private boolean deceased;
private Date birthDate;
private Integer salary; // null if unknown
private Double salaryDouble; // null if unknown
private BigDecimal rent;
public Person() {
}
@Override
public String toString() {
return "Person [firstName=" + firstName + ", lastName=" + lastName
+ ", email=" + email + ", age=" + age + ", sex=" + sex
+ ", address=" + address + ", deceased=" + deceased
+ ", salary=" + salary + ", salaryDouble=" + salaryDouble
+ ", rent=" + rent + "]";
}
public Person(String firstName, String lastName, String email, int age,
Sex sex, Address address) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.age = age;
this.sex = sex;
this.address = address;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public Sex getSex() {
return sex;
}
public void setSex(Sex sex) {
this.sex = sex;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public boolean getDeceased() {
return deceased;
}
public void setDeceased(boolean deceased) {
this.deceased = deceased;
}
public Integer getSalary() {
return salary;
}
public void setSalary(Integer salary) {
this.salary = salary;
}
public BigDecimal getRent() {
return rent;
}
public void setRent(BigDecimal rent) {
this.rent = rent;
}
public Double getSalaryDouble() {
return salaryDouble;
}
public void setSalaryDouble(Double salaryDouble) {
this.salaryDouble = salaryDouble;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
}

+ 15
- 0
tests/server-side/com/vaadin/tests/data/bean/Sex.java View File

@@ -0,0 +1,15 @@
package com.vaadin.tests.data.bean;
public enum Sex {
MALE("Male"), FEMALE("Female"), UNKNOWN("Unknown");
private String stringRepresentation;
private Sex(String stringRepresentation) {
this.stringRepresentation = stringRepresentation;
}
public String getStringRepresentation() {
return stringRepresentation;
}
}

+ 15
- 4
tests/server-side/com/vaadin/tests/server/TestSerialization.java View File

@@ -10,6 +10,7 @@ import java.io.Serializable;
import junit.framework.TestCase;

import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.data.util.MethodProperty;
import com.vaadin.data.validator.RegexpValidator;
@@ -19,9 +20,9 @@ public class TestSerialization extends TestCase {

public void testValidators() throws Exception {
RegexpValidator validator = new RegexpValidator(".*", "Error");
validator.isValid("aaa");
validator.validate("aaa");
RegexpValidator validator2 = (RegexpValidator) serializeAndDeserialize(validator);
validator2.isValid("aaa");
validator2.validate("aaa");
}

public void testForm() throws Exception {
@@ -78,15 +79,25 @@ public class TestSerialization extends TestCase {
data));
Serializable s2 = (Serializable) in.readObject();

// using special toString(Object) method to avoid calling
// Property.toString(), which will be temporarily disabled
if (s.equals(s2)) {
System.out.println(s + " equals " + s2);
System.out.println(toString(s) + " equals " + toString(s2));
} else {
System.out.println(s + " does NOT equal " + s2);
System.out.println(toString(s) + " does NOT equal " + toString(s2));
}

return s2;
}

private static String toString(Object o) {
if (o instanceof Property) {
return String.valueOf(((Property<?>) o).getValue());
} else {
return String.valueOf(o);
}
}

public static class Data implements Serializable {
private String dummyGetter;
private String dummyGetterAndSetter;

+ 164
- 0
tests/server-side/com/vaadin/tests/server/component/abstractfield/AbstractFieldValueConversions.java View File

@@ -0,0 +1,164 @@
package com.vaadin.tests.server.component.abstractfield;
import java.util.Locale;
import junit.framework.TestCase;
import com.vaadin.data.util.MethodProperty;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.data.util.converter.NumberToStringConverter;
import com.vaadin.tests.data.bean.Address;
import com.vaadin.tests.data.bean.Country;
import com.vaadin.tests.data.bean.Person;
import com.vaadin.tests.data.bean.Sex;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.TextField;
public class AbstractFieldValueConversions extends TestCase {
Person paulaBean = new Person("Paula", "Brilliant", "paula@brilliant.com",
34, Sex.FEMALE, new Address("Paula street 1", 12345, "P-town",
Country.FINLAND));
public void testWithoutConversion() {
TextField tf = new TextField();
tf.setPropertyDataSource(new MethodProperty<Person>(paulaBean,
"firstName"));
assertEquals("Paula", tf.getValue());
assertEquals("Paula", tf.getPropertyDataSource().getValue());
tf.setValue("abc");
assertEquals("abc", tf.getValue());
assertEquals("abc", tf.getPropertyDataSource().getValue());
assertEquals("abc", paulaBean.getFirstName());
}
public void testStringIdentityConversion() {
TextField tf = new TextField();
tf.setValueConverter(new Converter<String, String>() {
public String convertFromTargetToSource(String value, Locale locale) {
return value;
}
public String convertFromSourceToTarget(String value, Locale locale) {
return value;
}
public Class<String> getSourceType() {
return String.class;
}
public Class<String> getTargetType() {
return String.class;
}
});
tf.setPropertyDataSource(new MethodProperty<Person>(paulaBean,
"firstName"));
assertEquals("Paula", tf.getValue());
assertEquals("Paula", tf.getPropertyDataSource().getValue());
tf.setValue("abc");
assertEquals("abc", tf.getValue());
assertEquals("abc", tf.getPropertyDataSource().getValue());
assertEquals("abc", paulaBean.getFirstName());
}
public void testFailingConversion() {
TextField tf = new TextField();
tf.setValueConverter(new Converter<Integer, String>() {
public Integer convertFromTargetToSource(String value, Locale locale) {
throw new ConversionException("Failed");
}
public String convertFromSourceToTarget(Integer value, Locale locale) {
throw new ConversionException("Failed");
}
public Class<Integer> getSourceType() {
// TODO Auto-generated method stub
return null;
}
public Class<String> getTargetType() {
// TODO Auto-generated method stub
return null;
}
});
try {
tf.setValue(1);
fail("setValue(Integer) should throw an exception");
} catch (com.vaadin.data.Property.ConversionException e) {
// OK, expected
}
}
public void testIntegerStringConversion() {
TextField tf = new TextField();
tf.setValueConverter(new NumberToStringConverter());
tf.setPropertyDataSource(new MethodProperty<Person>(paulaBean, "age"));
assertEquals(34, tf.getPropertyDataSource().getValue());
assertEquals("34", tf.getValue());
tf.setValue("12");
assertEquals(12, tf.getPropertyDataSource().getValue());
assertEquals("12", tf.getValue());
tf.getPropertyDataSource().setValue(42);
assertEquals(42, tf.getPropertyDataSource().getValue());
assertEquals("42", tf.getValue());
}
public void testBooleanNullConversion() {
CheckBox cb = new CheckBox();
cb.setValueConverter(new Converter<Boolean, Boolean>() {
public Boolean convertFromTargetToSource(Boolean value,
Locale locale) {
// value from a CheckBox should never be null as long as it is
// not set to null (handled by conversion below).
assertNotNull(value);
return value;
}
public Boolean convertFromSourceToTarget(Boolean value,
Locale locale) {
// Datamodel -> field
if (value == null) {
return false;
}
return value;
}
public Class<Boolean> getSourceType() {
return Boolean.class;
}
public Class<Boolean> getTargetType() {
return Boolean.class;
}
});
MethodProperty<Person> property = new MethodProperty<Person>(paulaBean,
"deceased");
cb.setPropertyDataSource(property);
assertNull(property.getValue());
assertEquals(Boolean.FALSE, cb.getValue());
Boolean newDmValue = cb.getValueConverter().convertFromSourceToTarget(
cb.getValue(), new Locale("fi", "FI"));
assertEquals(Boolean.FALSE, newDmValue);
// FIXME: Should be able to set to false here to cause datamodel to be
// set to false but the change will not be propagated to the Property
// (field value is already false)
cb.setValue(true);
assertEquals(Boolean.TRUE, cb.getValue());
assertEquals(Boolean.TRUE, property.getValue());
cb.setValue(false);
assertEquals(Boolean.FALSE, cb.getValue());
assertEquals(Boolean.FALSE, property.getValue());
}
}

+ 55
- 0
tests/server-side/com/vaadin/tests/server/component/abstractfield/DefaultConverterFactory.java View File

@@ -0,0 +1,55 @@
package com.vaadin.tests.server.component.abstractfield;
import java.math.BigDecimal;
import java.util.Locale;
import junit.framework.TestCase;
import com.vaadin.Application;
import com.vaadin.data.util.MethodProperty;
import com.vaadin.tests.data.bean.Address;
import com.vaadin.tests.data.bean.Country;
import com.vaadin.tests.data.bean.Person;
import com.vaadin.tests.data.bean.Sex;
import com.vaadin.ui.TextField;
import com.vaadin.ui.Window;
public class DefaultConverterFactory extends TestCase {
Person paulaBean = new Person("Paula", "Brilliant", "paula@brilliant.com",
34, Sex.FEMALE, new Address("Paula street 1", 12345, "P-town",
Country.FINLAND));
{
paulaBean.setSalary(49000);
BigDecimal rent = new BigDecimal(57223);
rent = rent.scaleByPowerOfTen(-2);
paulaBean.setRent(rent);
}
public void testDefaultNumberConversion() {
Application app = new Application() {
@Override
public void init() {
}
};
app.setMainWindow(new Window());
TextField tf = new TextField();
app.getMainWindow().addComponent(tf);
tf.setLocale(new Locale("en", "US"));
tf.setPropertyDataSource(new MethodProperty<Person>(paulaBean, "salary"));
assertEquals("49,000", tf.getValue());
tf.setLocale(new Locale("fi", "FI"));
// FIXME: The following line should not be necessary and should be
// removed
tf.setPropertyDataSource(new MethodProperty<Person>(paulaBean, "salary"));
String value = tf.getValue();
// Java uses a non-breaking space (ascii 160) instead of space when
// formatting
String expected = "49" + (char) 160 + "000";
assertEquals(expected, value);
}
}

+ 7
- 7
tests/server-side/com/vaadin/tests/server/component/textfield/TextFieldWithPropertyFormatter.java View File

@@ -2,6 +2,8 @@ package com.vaadin.tests.server.component.textfield;

import java.util.Collections;

import junit.framework.TestCase;

import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
@@ -11,8 +13,6 @@ import com.vaadin.terminal.Paintable;
import com.vaadin.terminal.Paintable.RepaintRequestEvent;
import com.vaadin.ui.TextField;

import junit.framework.TestCase;

public class TextFieldWithPropertyFormatter extends TestCase {

private static final String INPUT_VALUE = "foo";
@@ -20,7 +20,7 @@ public class TextFieldWithPropertyFormatter extends TestCase {
private static final String FORMATTED_VALUE = "FOOBAR";
private static final String ORIGINAL_VALUE = "Original";
private TextField field;
private PropertyFormatter formatter;
private PropertyFormatter<String> formatter;
private ObjectProperty<String> property;
private ValueChangeListener listener;
private int listenerCalled;
@@ -32,16 +32,16 @@ public class TextFieldWithPropertyFormatter extends TestCase {

field = new TextField();

formatter = new PropertyFormatter() {
formatter = new PropertyFormatter<String>() {

@Override
public Object parse(String formattedValue) throws Exception {
public String parse(String formattedValue) throws Exception {
assertEquals(INPUT_VALUE, formattedValue);
return PARSED_VALUE;
}

@Override
public String format(Object value) {
public String format(String value) {
return FORMATTED_VALUE;
}
};
@@ -59,7 +59,7 @@ public class TextFieldWithPropertyFormatter extends TestCase {
assertEquals(FORMATTED_VALUE, event.getProperty().getValue());
}
};
field.addListener(listener);
field.addListener(new Paintable.RepaintRequestListener() {
public void repaintRequested(RepaintRequestEvent event) {

+ 5
- 5
tests/server-side/com/vaadin/tests/server/components/AbstractTestFieldValueChange.java View File

@@ -22,12 +22,12 @@ import com.vaadin.ui.AbstractField;
* override {@link #setValue(AbstractField)} to set the field value via
* <code>changeVariables()</code>.
*/
public abstract class AbstractTestFieldValueChange extends TestCase {
public abstract class AbstractTestFieldValueChange<T> extends TestCase {
private AbstractField field;
private AbstractField<T> field;
private ValueChangeListener listener;
protected void setUp(AbstractField field) throws Exception {
protected void setUp(AbstractField<T> field) throws Exception {
this.field = field;
listener = EasyMock.createStrictMock(ValueChangeListener.class);
@@ -155,14 +155,14 @@ public abstract class AbstractTestFieldValueChange extends TestCase {
EasyMock.verify(listener);
}
protected AbstractField getField() {
protected AbstractField<T> getField() {
return field;
}
/**
* Override in subclasses to set value with changeVariables().
*/
protected void setValue(AbstractField field) {
protected void setValue(AbstractField<T> field) {
field.setValue("newValue");
}

+ 3
- 2
tests/server-side/com/vaadin/tests/server/components/TestComboBoxValueChange.java View File

@@ -12,7 +12,8 @@ import com.vaadin.ui.ComboBox;
*
* See <a href="http://dev.vaadin.com/ticket/4394">Ticket 4394</a>.
*/
public class TestComboBoxValueChange extends AbstractTestFieldValueChange {
public class TestComboBoxValueChange extends
AbstractTestFieldValueChange<Object> {
@Override
protected void setUp() throws Exception {
ComboBox combo = new ComboBox();
@@ -21,7 +22,7 @@ public class TestComboBoxValueChange extends AbstractTestFieldValueChange {
}
@Override
protected void setValue(AbstractField field) {
protected void setValue(AbstractField<Object> field) {
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("selected", new String[] { "myvalue" });
field.changeVariables(field, variables);

+ 3
- 2
tests/server-side/com/vaadin/tests/server/components/TestTextFieldValueChange.java View File

@@ -18,7 +18,8 @@ import com.vaadin.ui.TextField;
*
* See <a href="http://dev.vaadin.com/ticket/4394">Ticket 4394</a>.
*/
public class TestTextFieldValueChange extends AbstractTestFieldValueChange {
public class TestTextFieldValueChange extends
AbstractTestFieldValueChange<String> {
@Override
protected void setUp() throws Exception {
@@ -36,7 +37,7 @@ public class TestTextFieldValueChange extends AbstractTestFieldValueChange {
}
@Override
protected void setValue(AbstractField field) {
protected void setValue(AbstractField<String> field) {
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("text", "newValue");
field.changeVariables(field, variables);

+ 1
- 1
tests/server-side/com/vaadin/tests/server/validation/TestReadOnlyValidation.java View File

@@ -11,7 +11,7 @@ public class TestReadOnlyValidation {
public void testIntegerValidation() {
TextField field = new TextField();
field.addValidator(new IntegerValidator("Enter a Valid Number"));
field.setValue(Integer.valueOf(10));
field.setValue(String.valueOf(10));
field.validate();
}
}

+ 8
- 1
tests/testbench/com/vaadin/tests/CustomLayoutDemo.java View File

@@ -5,6 +5,7 @@
package com.vaadin.tests;

import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Component.Event;
import com.vaadin.ui.Component.Listener;
import com.vaadin.ui.CustomLayout;
@@ -40,7 +41,13 @@ public class CustomLayoutDemo extends com.vaadin.Application.LegacyApplication

private final PasswordField loginPwd = new PasswordField("Password");

private final Button loginButton = new Button("Login", this, "loginClicked");
private final Button loginButton = new Button("Login",
new Button.ClickListener() {

public void buttonClick(ClickEvent event) {
loginClicked();
}
});

private final Tree menu = new Tree();


+ 11
- 2
tests/testbench/com/vaadin/tests/PerformanceTestSubTreeCaching.java View File

@@ -7,6 +7,7 @@ package com.vaadin.tests;
import java.util.Date;

import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.Label;
import com.vaadin.ui.Table;
@@ -36,10 +37,18 @@ public class PerformanceTestSubTreeCaching extends CustomComponent {
setCompositionRoot(main);
addInfo();

Button b = new Button("start test", this, "startTest");
Button b = new Button("start test", new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
startTest();
}
});
b.setDescription("Push this button to start test. A test label will be rendered above existing components.");
main.addComponent(b);
b = new Button("end test", this, "endTest");
b = new Button("end test", new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
endTest();
}
});
b.setDescription("Push this button as soon as test componenet is rendered.");
main.addComponent(b);


+ 12
- 4
tests/testbench/com/vaadin/tests/TestForChildComponentRendering.java View File

@@ -9,6 +9,7 @@ import java.util.Iterator;

import com.vaadin.terminal.ExternalResource;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Component;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.Label;
@@ -51,14 +52,21 @@ public class TestForChildComponentRendering extends CustomComponent {
se.addItem("valinta1");
se.addItem("Valinta 2");

Button b = new Button("refresh view", this, "createNewView");
Button b = new Button("refresh view", new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
createNewView();
}
});
main.addComponent(b);

b = new Button("reorder view", this, "randomReorder");
b = new Button("reorder view", new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
randomReorder();
}
});
main.addComponent(b);

b = new Button("remove randomly one component", this,
"removeRandomComponent");
b = new Button("remove randomly one component", new Button.ClickListener() { public void buttonClick(ClickEvent event) { removeRandomComponent();}});
main.addComponent(b);

}

+ 4
- 4
tests/testbench/com/vaadin/tests/TestForContainerFilterable.java View File

@@ -62,12 +62,12 @@ public class TestForContainerFilterable extends CustomComponent {
filterButton.addListener(new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
ic.removeAllContainerFilters();
if (fooFilter.toString().length() > 0) {
ic.addContainerFilter("foo", fooFilter.toString(), false,
if (fooFilter.getStringValue().length() > 0) {
ic.addContainerFilter("foo", fooFilter.getStringValue(), false,
false);
}
if (barFilter.toString().length() > 0) {
ic.addContainerFilter("bar", barFilter.toString(), true,
if (barFilter.getStringValue().length() > 0) {
ic.addContainerFilter("bar", barFilter.getStringValue(), true,
true);
}
count.setValue("Rows in table: " + ic.size());

+ 17
- 4
tests/testbench/com/vaadin/tests/TestForGridLayoutChildComponentRendering.java View File

@@ -9,6 +9,7 @@ import java.util.Iterator;

import com.vaadin.terminal.ExternalResource;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Component;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.GridLayout;
@@ -52,14 +53,26 @@ public class TestForGridLayoutChildComponentRendering extends CustomComponent {

main.addComponent(se, 0, 1, 1, 1);

Button b = new Button("refresh view", this, "createNewView");
Button b = new Button("refresh view", new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
createNewView();
}
});
main.addComponent(b);

b = new Button("reorder view", this, "randomReorder");
b = new Button("reorder view", new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
randomReorder();
}
});
main.addComponent(b);

b = new Button("remove randomly one component", this,
"removeRandomComponent");
b = new Button("remove randomly one component",
new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
removeRandomComponent();
}
});
main.addComponent(b);

}

+ 6
- 1
tests/testbench/com/vaadin/tests/TestForPreconfiguredComponents.java View File

@@ -90,7 +90,11 @@ public class TestForPreconfiguredComponents extends CustomComponent implements
test.setCaption("OptionGroup + multiselect manually (configured from select)");
main.addComponent(test);

final Button b = new Button("refresh view", this, "createNewView");
final Button b = new Button("refresh view", new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
createNewView();
}
});
main.addComponent(b);

}
@@ -160,6 +164,7 @@ public class TestForPreconfiguredComponents extends CustomComponent implements
t.addListener(new Listener() {
public void componentEvent(Event event) {
status.addComponent(new Label(event.getClass().getName()));
// TODO should not use Field.toString()
status.addComponent(new Label("selected: "
+ event.getSource().toString()));
}

+ 0
- 0
tests/testbench/com/vaadin/tests/TestForStyledUpload.java View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save