From: Leif Åstrand Date: Tue, 10 Jan 2017 10:22:22 +0000 (+0200) Subject: Allow AbstractField to override value equality (#8201) X-Git-Tag: 8.0.0.beta2~93 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=b4af93bebf1b7e51d33330c42e3c89d5e3e4fd45;p=vaadin-framework.git Allow AbstractField to override value equality (#8201) * Allow AbstractField to override value equality Fixes #8089 --- diff --git a/server/src/main/java/com/vaadin/ui/AbstractField.java b/server/src/main/java/com/vaadin/ui/AbstractField.java index f19e1fd8fc..9f1a275ad0 100644 --- a/server/src/main/java/com/vaadin/ui/AbstractField.java +++ b/server/src/main/java/com/vaadin/ui/AbstractField.java @@ -133,7 +133,7 @@ public abstract class AbstractField extends AbstractComponent if (userOriginated && isReadOnly()) { return false; } - if (Objects.equals(value, getValue())) { + if (!isDifferentValue(value)) { return false; } doSetValue(value); @@ -145,6 +145,24 @@ public abstract class AbstractField extends AbstractComponent return true; } + /** + * Called when a new value is set to determine whether the provided new + * value is considered to be a change compared to the current value. This is + * used to determine whether {@link #doSetValue(Object)} should be called + * and a value change event fired. + * + * @param newValue + * the new value candidate to check, may be null + * + * @return true if the provided value is considered to be + * different and a value change event should be fired; + * false if the values are considered to be the same + * and no value change should be fired + */ + protected boolean isDifferentValue(T newValue) { + return !Objects.equals(newValue, getValue()); + } + /** * Sets the value of this field. May do sanitization or throw * {@code IllegalArgumentException} if the value is invalid. Typically saves diff --git a/server/src/test/java/com/vaadin/ui/AbstractFieldTest.java b/server/src/test/java/com/vaadin/ui/AbstractFieldTest.java index 7f66ca5ed3..8d8d9a6499 100644 --- a/server/src/test/java/com/vaadin/ui/AbstractFieldTest.java +++ b/server/src/test/java/com/vaadin/ui/AbstractFieldTest.java @@ -15,6 +15,14 @@ import com.vaadin.server.ClientConnector; public class AbstractFieldTest extends EasyMockSupport { + private final class IdentityTextField extends TextField { + @Override + protected boolean isDifferentValue(String newValue) { + // Checks for identity instead of equality + return newValue != getValue(); + } + } + class TextField extends AbstractField { String value = ""; @@ -119,4 +127,53 @@ public class AbstractFieldTest extends EasyMockSupport { assertSame("event source connector", source, e.getSource()); assertEquals("event from user", userOriginated, e.isUserOriginated()); } + + @Test + public void identityField_realChange() { + TextField identityField = new IdentityTextField(); + + identityField.addValueChangeListener(l); + + // Expect event to both listeners for actual change + l.valueChange(EasyMock.capture(capture)); + + replayAll(); + + identityField.setValue("value"); + + verifyAll(); + } + + @Test + public void identityField_onlyIdentityChange() { + TextField identityField = new IdentityTextField(); + identityField.setValue("value"); + + identityField.addValueChangeListener(l); + + // Expect event to both listeners for actual change + l.valueChange(EasyMock.capture(capture)); + + replayAll(); + + String sameValueDifferentIdentity = new String("value"); + identityField.setValue(sameValueDifferentIdentity); + + verifyAll(); + } + + @Test + public void identityField_noChange() { + TextField identityField = new IdentityTextField(); + identityField.setValue("value"); + + identityField.addValueChangeListener(l); + + // Expect no event for identical value + replayAll(); + + identityField.setValue(identityField.getValue()); + + verifyAll(); + } }