From 4cacbf7d7fda2918bfb030c49cc6776a07bf6a9c Mon Sep 17 00:00:00 2001 From: Teemu Suo-Anttila Date: Thu, 8 Feb 2018 15:21:33 +0200 Subject: Add setReadOnly for Bindings (#10482) --- server/src/main/java/com/vaadin/data/Binder.java | 118 ++++++++++++++++++----- 1 file changed, 95 insertions(+), 23 deletions(-) (limited to 'server/src/main/java/com/vaadin/data') diff --git a/server/src/main/java/com/vaadin/data/Binder.java b/server/src/main/java/com/vaadin/data/Binder.java index 8f25e92aba..406784fda4 100644 --- a/server/src/main/java/com/vaadin/data/Binder.java +++ b/server/src/main/java/com/vaadin/data/Binder.java @@ -176,6 +176,50 @@ public class Binder implements Serializable { * @since 8.2 */ public void read(BEAN bean); + + /** + * Sets the read-only status on for this Binding. Setting a Binding + * read-only will mark the field read-only and not write any values from + * the fields to the bean. + *

+ * This helper method is the preferred way to control the read-only + * state of the bound field. + * + * @param readOnly + * {@code true} to set binding read-only; {@code false} to + * enable writes + * @since + * @throws IllegalStateException + * if trying to make binding read-write and the setter is + * {@code null} + */ + public void setReadOnly(boolean readOnly); + + /** + * Gets the current read-only status for this Binding. + * + * @see #setReadOnly(boolean) + * + * @return {@code true} if read-only; {@code false} if not + * @since + */ + public boolean isReadOnly(); + + /** + * Gets the getter associated with this Binding. + * + * @return the getter + * @since + */ + public ValueProvider getGetter(); + + /** + * Gets the setter associated with this Binding. + * + * @return the setter + * @since + */ + public Setter getSetter(); } /** @@ -229,8 +273,9 @@ public class Binder implements Serializable { * * *

- * Note: when a {@code null} setter is given the field will be - * marked as readonly by invoking ({@link HasValue::setReadOnly}. + * Note: when a {@code null} setter is given the field + * will be marked as read-only by invoking + * {@link HasValue#setReadOnly(boolean)}. * * @param getter * the function to get the value of the property to the @@ -261,8 +306,9 @@ public class Binder implements Serializable { * updated and the binding is said to be read-only. * *

- * Note: when the binding is read-only the field will be - * marked as readonly by invoking ({@link HasValue::setReadOnly}. + * Note: when the binding is read-only the field + * will be marked as read-only by invoking + * {@link HasValue#setReadOnly(boolean)}. * * @param propertyName * the name of the property to bind, not null @@ -776,7 +822,8 @@ public class Binder implements Serializable { ValueProvider getter = definition.getGetter(); Setter setter = definition.getSetter().orElse(null); if (setter == null) { - getLogger().fine(() -> propertyName + " does not have an accessible setter"); + getLogger().fine(() -> propertyName + + " does not have an accessible setter"); } BindingBuilder finalBinding = withConverter( @@ -930,9 +977,11 @@ public class Binder implements Serializable { private HasValue field; private final BindingValidationStatusHandler statusHandler; - private final SerializableFunction getter; + private final ValueProvider getter; private final Setter setter; + private boolean readOnly; + // Not final since we temporarily remove listener while changing values private Registration onValueChange; @@ -943,7 +992,7 @@ public class Binder implements Serializable { private final Converter converterValidatorChain; public BindingImpl(BindingBuilderImpl builder, - SerializableFunction getter, + ValueProvider getter, Setter setter) { this.binder = builder.getBinder(); this.field = builder.field; @@ -955,6 +1004,7 @@ public class Binder implements Serializable { this.getter = getter; this.setter = setter; + readOnly = setter == null; } @Override @@ -1105,7 +1155,7 @@ public class Binder implements Serializable { assert bean != null; Result result = doConversion(); - if (setter != null) { + if (!isReadOnly()) { result.ifOk(value -> setter.accept(bean, value)); } return toValidationStatus(result); @@ -1131,6 +1181,31 @@ public class Binder implements Serializable { field.setValue(converterValidatorChain.convertToPresentation( getter.apply(bean), createValueContext())); } + + @Override + public void setReadOnly(boolean readOnly) { + if (setter == null && !readOnly) { + throw new IllegalStateException( + "Binding with a null setter has to be read-only"); + } + this.readOnly = readOnly; + getField().setReadOnly(readOnly); + } + + @Override + public boolean isReadOnly() { + return readOnly; + } + + @Override + public ValueProvider getGetter() { + return getter; + } + + @Override + public Setter getSetter() { + return setter; + } } /** @@ -1456,8 +1531,8 @@ public class Binder implements Serializable { * * *

- * Note: when a {@code null} setter is given the field will be - * marked as readonly by invoking ({@link HasValue::setReadOnly}. + * Note: when a {@code null} setter is given the field will + * be marked as read-only by invoking {@link HasValue#setReadOnly(boolean)}. * * @param * the value type of the field @@ -2291,22 +2366,19 @@ public class Binder implements Serializable { } /** - * Sets the read only state to the given value for all currently bound - * fields. + * Sets the read only state to the given value for all current bindings. *

- * This is just a shorthand for calling setReadOnly for all currently bound - * fields. It means that fields bound after this method call won't be set - * read-only. + * This is just a shorthand for calling {@link Binding#setReadOnly(boolean)} + * for all current bindings. It means that bindings added after this method + * call won't be set read-only. * - * @param fieldsReadOnly - * true to set the fields to read only, false to set them to read - * write + * @param readOnly + * {@code true} to set the bindings to read-only, {@code false} + * to set them to read-write */ - public void setReadOnly(boolean fieldsReadOnly) { - getBindings().stream() - .filter(binding -> Objects.nonNull(binding.setter)) - .map(BindingImpl::getField) - .forEach(field -> field.setReadOnly(fieldsReadOnly)); + public void setReadOnly(boolean readOnly) { + getBindings().stream().filter(binding -> binding.getSetter() != null) + .forEach(binding -> binding.setReadOnly(readOnly)); } /** -- cgit v1.2.3