* @throws IllegalArgumentException | * @throws IllegalArgumentException | ||||
* if the property has no accessible getter | * if the property has no accessible getter | ||||
* | * | ||||
* @see BindingBuilder#bind(SerializableFunction, | |||||
* @see BindingBuilder#bind(ValueProvider, | |||||
* SerializableBiConsumer) | * SerializableBiConsumer) | ||||
*/ | */ | ||||
public Binding<BEAN, TARGET> bind(String propertyName); | public Binding<BEAN, TARGET> bind(String propertyName); | ||||
* @throws IllegalArgumentException | * @throws IllegalArgumentException | ||||
* if the property has no accessible getter | * if the property has no accessible getter | ||||
* | * | ||||
* @see #bind(HasValue, SerializableFunction, SerializableBiConsumer) | |||||
* @see #bind(HasValue, ValueProvider, SerializableBiConsumer) | |||||
*/ | */ | ||||
public <FIELDVALUE> Binding<BEAN, FIELDVALUE> bind( | public <FIELDVALUE> Binding<BEAN, FIELDVALUE> bind( | ||||
HasValue<FIELDVALUE> field, String propertyName) { | HasValue<FIELDVALUE> field, String propertyName) { |
* if {@code bind} has already been called on this binding | * if {@code bind} has already been called on this binding | ||||
*/ | */ | ||||
public Binding<BEAN, TARGET> bind( | public Binding<BEAN, TARGET> bind( | ||||
SerializableFunction<BEAN, TARGET> getter, | |||||
ValueProvider<BEAN, TARGET> getter, | |||||
com.vaadin.server.SerializableBiConsumer<BEAN, TARGET> setter); | com.vaadin.server.SerializableBiConsumer<BEAN, TARGET> setter); | ||||
/** | /** | ||||
* which must match the current target data type of the binding, and a | * which must match the current target data type of the binding, and a | ||||
* model type, which can be any data type and becomes the new target | * model type, which can be any data type and becomes the new target | ||||
* type of the binding. When invoking | * type of the binding. When invoking | ||||
* {@link #bind(SerializableFunction, SerializableBiConsumer)}, the | |||||
* {@link #bind(ValueProvider, SerializableBiConsumer)}, the | |||||
* target type of the binding must match the getter/setter types. | * target type of the binding must match the getter/setter types. | ||||
* <p> | * <p> | ||||
* For instance, a {@code TextField} can be bound to an integer-typed | * For instance, a {@code TextField} can be bound to an integer-typed | ||||
* type, which must match the current target data type of the binding, | * type, which must match the current target data type of the binding, | ||||
* and a model type, which can be any data type and becomes the new | * and a model type, which can be any data type and becomes the new | ||||
* target type of the binding. When invoking | * target type of the binding. When invoking | ||||
* {@link #bind(SerializableFunction, SerializableBiConsumer)}, the | |||||
* {@link #bind(ValueProvider, SerializableBiConsumer)}, the | |||||
* target type of the binding must match the getter/setter types. | * target type of the binding must match the getter/setter types. | ||||
* <p> | * <p> | ||||
* For instance, a {@code TextField} can be bound to an integer-typed | * For instance, a {@code TextField} can be bound to an integer-typed | ||||
* type, which must match the current target data type of the binding, | * type, which must match the current target data type of the binding, | ||||
* and a model type, which can be any data type and becomes the new | * and a model type, which can be any data type and becomes the new | ||||
* target type of the binding. When invoking | * target type of the binding. When invoking | ||||
* {@link #bind(SerializableFunction, SerializableBiConsumer)}, the | |||||
* {@link #bind(ValueProvider, SerializableBiConsumer)}, the | |||||
* target type of the binding must match the getter/setter types. | * target type of the binding must match the getter/setter types. | ||||
* <p> | * <p> | ||||
* For instance, a {@code TextField} can be bound to an integer-typed | * For instance, a {@code TextField} can be bound to an integer-typed | ||||
@Override | @Override | ||||
public Binding<BEAN, TARGET> bind( | public Binding<BEAN, TARGET> bind( | ||||
SerializableFunction<BEAN, TARGET> getter, | |||||
ValueProvider<BEAN, TARGET> getter, | |||||
SerializableBiConsumer<BEAN, TARGET> setter) { | SerializableBiConsumer<BEAN, TARGET> setter) { | ||||
checkUnbound(); | checkUnbound(); | ||||
Objects.requireNonNull(getter, "getter cannot be null"); | Objects.requireNonNull(getter, "getter cannot be null"); | ||||
/** | /** | ||||
* Creates a new binding for the given field. The returned builder may be | * Creates a new binding for the given field. The returned builder may be | ||||
* further configured before invoking | * further configured before invoking | ||||
* {@link BindingBuilder#bind(SerializableFunction, SerializableBiConsumer)} | |||||
* {@link BindingBuilder#bind(ValueProvider, SerializableBiConsumer)} | |||||
* which completes the binding. Until {@code Binding.bind} is called, the | * which completes the binding. Until {@code Binding.bind} is called, the | ||||
* binding has no effect. | * binding has no effect. | ||||
* <p> | * <p> | ||||
* the field to be bound, not null | * the field to be bound, not null | ||||
* @return the new binding | * @return the new binding | ||||
* | * | ||||
* @see #bind(HasValue, SerializableFunction, SerializableBiConsumer) | |||||
* @see #bind(HasValue, ValueProvider, SerializableBiConsumer) | |||||
*/ | */ | ||||
public <FIELDVALUE> BindingBuilder<BEAN, FIELDVALUE> forField( | public <FIELDVALUE> BindingBuilder<BEAN, FIELDVALUE> forField( | ||||
HasValue<FIELDVALUE> field) { | HasValue<FIELDVALUE> field) { | ||||
*/ | */ | ||||
public <FIELDVALUE> Binding<BEAN, FIELDVALUE> bind( | public <FIELDVALUE> Binding<BEAN, FIELDVALUE> bind( | ||||
HasValue<FIELDVALUE> field, | HasValue<FIELDVALUE> field, | ||||
SerializableFunction<BEAN, FIELDVALUE> getter, | |||||
ValueProvider<BEAN, FIELDVALUE> getter, | |||||
SerializableBiConsumer<BEAN, FIELDVALUE> setter) { | SerializableBiConsumer<BEAN, FIELDVALUE> setter) { | ||||
return forField(field).bind(getter, setter); | return forField(field).bind(getter, setter); | ||||
} | } | ||||
* <li>{@link #setBean(Object)} is called | * <li>{@link #setBean(Object)} is called | ||||
* <li>{@link #removeBean()} is called | * <li>{@link #removeBean()} is called | ||||
* <li> | * <li> | ||||
* {@link BindingBuilder#bind(SerializableFunction, SerializableBiConsumer)} | |||||
* {@link BindingBuilder#bind(ValueProvider, SerializableBiConsumer)} | |||||
* is called | * is called | ||||
* <li>{@link Binder#validate()} or {@link Binding#validate()} is called | * <li>{@link Binder#validate()} or {@link Binding#validate()} is called | ||||
* </ul> | * </ul> |
* values. Specific implementations might not support this. | * values. Specific implementations might not support this. | ||||
* | * | ||||
* @return empty value | * @return empty value | ||||
* @see Binder#bind(HasValue, java.util.function.Function, BiConsumer) | |||||
* @see Binder#bind(HasValue, ValueProvider, BiConsumer) | |||||
*/ | */ | ||||
public default V getEmptyValue() { | public default V getEmptyValue() { | ||||
return null; | return null; |
import com.vaadin.data.Binder.Binding; | import com.vaadin.data.Binder.Binding; | ||||
import com.vaadin.data.Binder.BindingBuilder; | import com.vaadin.data.Binder.BindingBuilder; | ||||
import com.vaadin.server.SerializableBiConsumer; | import com.vaadin.server.SerializableBiConsumer; | ||||
import com.vaadin.server.SerializableFunction; | |||||
/** | /** | ||||
* Binder status change event. | * Binder status change event. | ||||
* <li>{@link Binder#readBean(Object)} is called | * <li>{@link Binder#readBean(Object)} is called | ||||
* <li>{@link Binder#setBean(Object)} is called | * <li>{@link Binder#setBean(Object)} is called | ||||
* <li>{@link Binder#removeBean()} is called | * <li>{@link Binder#removeBean()} is called | ||||
* <li>{@link BindingBuilder#bind(SerializableFunction, SerializableBiConsumer)} | |||||
* <li>{@link BindingBuilder#bind(ValueProvider, SerializableBiConsumer)} | |||||
* is called | * is called | ||||
* <li>{@link Binder#validate()} or {@link Binding#validate()} is called | * <li>{@link Binder#validate()} or {@link Binding#validate()} is called | ||||
* </ul> | * </ul> |
/* | |||||
* Copyright 2000-2016 Vaadin Ltd. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||||
* use this file except in compliance with the License. You may obtain a copy of | |||||
* the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||||
* License for the specific language governing permissions and limitations under | |||||
* the License. | |||||
*/ | |||||
package com.vaadin.data; | |||||
import com.vaadin.server.SerializableFunction; | |||||
/** | |||||
* A callback interface for providing values from a given source. | |||||
* <p> | |||||
* For example this interface can be implemented to simply extract a value with | |||||
* a getter, or to create a composite value based on the fields of the source | |||||
* object. | |||||
* | |||||
* @author Vaadin Ltd. | |||||
* @since 8.0 | |||||
* | |||||
* @param <SOURCE> | |||||
* the type of the object used to provide the value | |||||
* @param <TARGET> | |||||
* the type of the provided value | |||||
*/ | |||||
@FunctionalInterface | |||||
public interface ValueProvider<SOURCE, TARGET> | |||||
extends SerializableFunction<SOURCE, TARGET> { | |||||
/** | |||||
* Returns a value provider that always returns its input argument. | |||||
* | |||||
* @param <T> | |||||
* the type of the input and output objects to the function | |||||
* @return a function that always returns its input argument | |||||
*/ | |||||
public static <T> ValueProvider<T, T> identity() { | |||||
return t -> t; | |||||
} | |||||
/** | |||||
* Provides a value from the given source object. | |||||
* | |||||
* @param source | |||||
* the source to retrieve the value from | |||||
* @return the value provided by the source | |||||
*/ | |||||
@Override | |||||
public TARGET apply(SOURCE source); | |||||
} |
import java.util.IdentityHashMap; | import java.util.IdentityHashMap; | ||||
import java.util.Map; | import java.util.Map; | ||||
import com.vaadin.server.SerializableFunction; | |||||
import com.vaadin.data.ValueProvider; | |||||
/** | /** | ||||
* Value provider class for declarative support. | * Value provider class for declarative support. | ||||
* @param <T> | * @param <T> | ||||
* item type | * item type | ||||
*/ | */ | ||||
class DeclarativeValueProvider<T> implements SerializableFunction<T, String> { | |||||
class DeclarativeValueProvider<T> implements ValueProvider<T, String> { | |||||
private final Map<T, String> values = new IdentityHashMap<>(); | private final Map<T, String> values = new IdentityHashMap<>(); | ||||
import com.vaadin.data.BinderValidationStatus; | import com.vaadin.data.BinderValidationStatus; | ||||
import com.vaadin.data.Listing; | import com.vaadin.data.Listing; | ||||
import com.vaadin.data.SelectionModel; | import com.vaadin.data.SelectionModel; | ||||
import com.vaadin.data.ValueProvider; | |||||
import com.vaadin.event.ConnectorEvent; | import com.vaadin.event.ConnectorEvent; | ||||
import com.vaadin.event.ContextClickEvent; | import com.vaadin.event.ContextClickEvent; | ||||
import com.vaadin.event.SerializableEventListener; | import com.vaadin.event.SerializableEventListener; | ||||
* the type of value | * the type of value | ||||
*/ | */ | ||||
protected Column(String caption, | protected Column(String caption, | ||||
SerializableFunction<T, ? extends V> valueProvider, | |||||
ValueProvider<T, ? extends V> valueProvider, | |||||
Renderer<V> renderer) { | Renderer<V> renderer) { | ||||
Objects.requireNonNull(caption, "Header caption can't be null"); | Objects.requireNonNull(caption, "Header caption can't be null"); | ||||
Objects.requireNonNull(valueProvider, | Objects.requireNonNull(valueProvider, | ||||
* @see AbstractRenderer | * @see AbstractRenderer | ||||
*/ | */ | ||||
public <V> Column<T, V> addColumn(String identifier, | public <V> Column<T, V> addColumn(String identifier, | ||||
SerializableFunction<T, ? extends V> valueProvider, | |||||
ValueProvider<T, ? extends V> valueProvider, | |||||
AbstractRenderer<? super T, V> renderer) | AbstractRenderer<? super T, V> renderer) | ||||
throws IllegalArgumentException { | throws IllegalArgumentException { | ||||
if (columnKeys.containsKey(identifier)) { | if (columnKeys.containsKey(identifier)) { | ||||
* if the same identifier is used for multiple columns | * if the same identifier is used for multiple columns | ||||
*/ | */ | ||||
public Column<T, String> addColumn(String identifier, | public Column<T, String> addColumn(String identifier, | ||||
SerializableFunction<T, String> valueProvider) { | |||||
ValueProvider<T, String> valueProvider) { | |||||
return addColumn(identifier, valueProvider, new TextRenderer()); | return addColumn(identifier, valueProvider, new TextRenderer()); | ||||
} | } | ||||
* @return the new column | * @return the new column | ||||
*/ | */ | ||||
public Column<T, String> addColumn( | public Column<T, String> addColumn( | ||||
SerializableFunction<T, ?> valueProvider) { | |||||
ValueProvider<T, String> valueProvider) { | |||||
return addColumn(getGeneratedIdentifier(), | return addColumn(getGeneratedIdentifier(), | ||||
t -> String.valueOf(valueProvider.apply(t)), | t -> String.valueOf(valueProvider.apply(t)), | ||||
new TextRenderer()); | new TextRenderer()); | ||||
* @see AbstractRenderer | * @see AbstractRenderer | ||||
*/ | */ | ||||
public <V> Column<T, V> addColumn( | public <V> Column<T, V> addColumn( | ||||
SerializableFunction<T, ? extends V> valueProvider, | |||||
ValueProvider<T, ? extends V> valueProvider, | |||||
AbstractRenderer<? super T, V> renderer) { | AbstractRenderer<? super T, V> renderer) { | ||||
return addColumn(getGeneratedIdentifier(), valueProvider, renderer); | return addColumn(getGeneratedIdentifier(), valueProvider, renderer); | ||||
} | } |
import org.junit.Before; | import org.junit.Before; | ||||
import org.junit.Test; | import org.junit.Test; | ||||
import com.vaadin.server.SerializableFunction; | |||||
import com.vaadin.data.ValueProvider; | |||||
import com.vaadin.ui.Grid; | import com.vaadin.ui.Grid; | ||||
import com.vaadin.ui.Grid.Column; | import com.vaadin.ui.Grid.Column; | ||||
import com.vaadin.ui.Grid.HeaderRow; | import com.vaadin.ui.Grid.HeaderRow; | ||||
public void setUp() { | public void setUp() { | ||||
grid = new Grid<>(); | grid = new Grid<>(); | ||||
column1 = grid.addColumn("First", SerializableFunction.identity()); | |||||
column2 = grid.addColumn("Second", SerializableFunction.identity()); | |||||
column1 = grid.addColumn("First", ValueProvider.identity()); | |||||
column2 = grid.addColumn("Second", ValueProvider.identity()); | |||||
} | } | ||||
@Test | @Test |
import org.junit.Before; | import org.junit.Before; | ||||
import org.junit.Test; | import org.junit.Test; | ||||
import com.vaadin.server.SerializableFunction; | |||||
import com.vaadin.data.ValueProvider; | |||||
import com.vaadin.ui.Grid; | import com.vaadin.ui.Grid; | ||||
import com.vaadin.ui.Grid.Column; | import com.vaadin.ui.Grid.Column; | ||||
import com.vaadin.ui.Grid.HeaderRow; | import com.vaadin.ui.Grid.HeaderRow; | ||||
@Test | @Test | ||||
public void addColumn_headerCellAdded() { | public void addColumn_headerCellAdded() { | ||||
Column<?, ?> column = grid.addColumn("Col", | Column<?, ?> column = grid.addColumn("Col", | ||||
SerializableFunction.identity()); | |||||
ValueProvider.identity()); | |||||
assertNotNull(grid.getHeaderRow(0).getCell(column)); | assertNotNull(grid.getHeaderRow(0).getCell(column)); | ||||
} | } | ||||
@Test(expected = IllegalArgumentException.class) | @Test(expected = IllegalArgumentException.class) | ||||
public void removeColumn_headerCellRemoved() { | public void removeColumn_headerCellRemoved() { | ||||
Column<String, ?> column = grid.addColumn("Col", | Column<String, ?> column = grid.addColumn("Col", | ||||
SerializableFunction.identity()); | |||||
ValueProvider.identity()); | |||||
grid.removeColumn(column); | grid.removeColumn(column); | ||||
grid.getHeaderRow(0).getCell(column); | grid.getHeaderRow(0).getCell(column); |
import org.junit.Before; | import org.junit.Before; | ||||
import org.junit.Test; | import org.junit.Test; | ||||
import com.vaadin.data.ValueProvider; | |||||
import com.vaadin.event.selection.SelectionEvent; | import com.vaadin.event.selection.SelectionEvent; | ||||
import com.vaadin.server.SerializableFunction; | |||||
import com.vaadin.shared.ui.grid.HeightMode; | import com.vaadin.shared.ui.grid.HeightMode; | ||||
import com.vaadin.ui.Grid; | import com.vaadin.ui.Grid; | ||||
import com.vaadin.ui.Grid.SelectionMode; | import com.vaadin.ui.Grid.SelectionMode; | ||||
@Before | @Before | ||||
public void setUp() { | public void setUp() { | ||||
grid = new Grid<>(); | grid = new Grid<>(); | ||||
grid.addColumn("foo", SerializableFunction.identity()); | |||||
grid.addColumn("foo", ValueProvider.identity()); | |||||
grid.addColumn(String::length, new NumberRenderer()); | grid.addColumn(String::length, new NumberRenderer()); | ||||
grid.addColumn("randomColumnId", SerializableFunction.identity()); | |||||
grid.addColumn("randomColumnId", ValueProvider.identity()); | |||||
} | } | ||||
@Test | @Test |
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.List; | import java.util.List; | ||||
import com.vaadin.server.SerializableFunction; | |||||
import com.vaadin.data.ValueProvider; | |||||
import com.vaadin.server.VaadinRequest; | import com.vaadin.server.VaadinRequest; | ||||
import com.vaadin.server.data.DataProvider; | import com.vaadin.server.data.DataProvider; | ||||
import com.vaadin.tests.components.AbstractTestUI; | import com.vaadin.tests.components.AbstractTestUI; | ||||
protected void setup(VaadinRequest request) { | protected void setup(VaadinRequest request) { | ||||
Grid<String> grid = new Grid<>(); | Grid<String> grid = new Grid<>(); | ||||
grid.addColumn("Name", SerializableFunction.identity()); | |||||
grid.addColumn("Name", ValueProvider.identity()); | |||||
List<String> data = new ArrayList<>(); | List<String> data = new ArrayList<>(); | ||||
for (int i = 0; i < 1000; i++) { | for (int i = 0; i < 1000; i++) { |