Change-Id: I3c24e1f0996cdbbc13142d5a95bf5efb550331f7feature/vaadin8-book-vol2
@@ -66,7 +66,7 @@ public class DateFieldConnector extends AbstractComponentConnector { | |||
w.getElement().setAttribute("placeholder", "DD-MM-YYYY"); | |||
w.getElement().setAttribute("maxlength", "10"); | |||
w.setValue(state.value); | |||
w.setValue(state.date); | |||
} | |||
} |
@@ -0,0 +1,79 @@ | |||
/* | |||
* Copyright 2000-2014 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.tokka.ui.components.fields; | |||
import java.io.Serializable; | |||
import java.util.Objects; | |||
import java.util.function.Consumer; | |||
import com.vaadin.tokka.event.Registration; | |||
import com.vaadin.tokka.ui.components.HasValue; | |||
import com.vaadin.ui.AbstractComponent; | |||
public abstract class AbstractField<T> extends AbstractComponent | |||
implements HasValue<T> { | |||
@Override | |||
public void setValue(T value) { | |||
setValue(value, false); | |||
} | |||
public <L extends Consumer<T> & Serializable> Registration onValueChange( | |||
L listener) { | |||
return addValueChangeListener(e -> listener.accept(e.getValue())); | |||
} | |||
/** | |||
* Sets the value of this field. | |||
* | |||
* @param value | |||
* the new value to set | |||
* @param userOriginated | |||
* whether the value change originates from the user | |||
*/ | |||
protected <E extends ValueChange<T>> void setValue(T value, | |||
boolean userOriginated) { | |||
if (userOriginated && isReadOnly()) { | |||
return; | |||
} | |||
if (Objects.equals(value, getValue())) { | |||
return; | |||
} | |||
doSetValue(value); | |||
if (!userOriginated) { | |||
markAsDirty(); | |||
} | |||
fireEvent(createValueChange(userOriginated)); | |||
} | |||
/** | |||
* Stores the given field value to the shared state. | |||
* | |||
* @param value | |||
* the new value of the field | |||
*/ | |||
protected abstract void doSetValue(T value); | |||
/** | |||
* Returns a new value change event instance. | |||
* | |||
* @param userOriginated | |||
* whether the value change originates from the user | |||
* @return the new event | |||
*/ | |||
protected abstract ValueChange<T> createValueChange(boolean userOriginated); | |||
} |
@@ -29,8 +29,6 @@ import com.vaadin.shared.tokka.ui.components.fields.TextFieldServerRpc; | |||
import com.vaadin.shared.tokka.ui.components.fields.TextFieldState; | |||
import com.vaadin.tokka.event.EventListener; | |||
import com.vaadin.tokka.event.Registration; | |||
import com.vaadin.tokka.ui.components.HasValue; | |||
import com.vaadin.ui.AbstractComponent; | |||
import com.vaadin.ui.declarative.DesignAttributeHandler; | |||
import com.vaadin.ui.declarative.DesignContext; | |||
@@ -39,12 +37,11 @@ import com.vaadin.ui.declarative.DesignContext; | |||
* | |||
* @author Vaadin Ltd. | |||
*/ | |||
public abstract class AbstractTextField extends AbstractComponent | |||
implements HasValue<String> { | |||
public abstract class AbstractTextField extends AbstractField<String> { | |||
public static class TextChange extends ValueChange<String> { | |||
public TextChange(AbstractTextField source, boolean userOriginated) { | |||
super(source, userOriginated); | |||
public class TextChange extends ValueChange<String> { | |||
public TextChange(boolean userOriginated) { | |||
super(AbstractTextField.this, userOriginated); | |||
} | |||
} | |||
@@ -63,24 +60,11 @@ public abstract class AbstractTextField extends AbstractComponent | |||
@Override | |||
public void setText(String text) { | |||
if (!isReadOnly()) { | |||
setValue(text); | |||
fireEvent(new TextChange(AbstractTextField.this, true)); | |||
} | |||
setValue(text, true); | |||
} | |||
}); | |||
} | |||
@Override | |||
protected TextFieldState getState() { | |||
return (TextFieldState) super.getState(); | |||
} | |||
@Override | |||
protected TextFieldState getState(boolean markAsDirty) { | |||
return (TextFieldState) super.getState(markAsDirty); | |||
} | |||
/** | |||
* Returns the maximum number of characters in the field. Value -1 is | |||
* considered unlimited. Terminal may however have some technical limits. | |||
@@ -123,19 +107,14 @@ public abstract class AbstractTextField extends AbstractComponent | |||
getState().placeholder = placeholder; | |||
} | |||
@Override | |||
public void setValue(String text) { | |||
// TODO Accept nulls or not? | |||
getState().text = text; | |||
} | |||
@Override | |||
public String getValue() { | |||
return getState(false).text; | |||
} | |||
@Override | |||
public Registration addValueChangeListener(EventListener<ValueChange<String>> listener) { | |||
public Registration addValueChangeListener( | |||
EventListener<ValueChange<String>> listener) { | |||
return addListener(TextChange.class, listener); | |||
} | |||
@@ -176,24 +155,20 @@ public abstract class AbstractTextField extends AbstractComponent | |||
setSelection(pos, 0); | |||
} | |||
@Deprecated | |||
public void addFocusListener(FocusListener listener) { | |||
addListener(FocusEvent.EVENT_ID, FocusEvent.class, listener, | |||
FocusListener.focusMethod); | |||
} | |||
@Deprecated | |||
public void removeFocusListener(FocusListener listener) { | |||
removeListener(FocusEvent.EVENT_ID, FocusEvent.class, listener); | |||
} | |||
@Deprecated | |||
public void addBlurListener(BlurListener listener) { | |||
addListener(BlurEvent.EVENT_ID, BlurEvent.class, listener, | |||
BlurListener.blurMethod); | |||
} | |||
@Deprecated | |||
public void removeBlurListener(BlurListener listener) { | |||
removeListener(BlurEvent.EVENT_ID, BlurEvent.class, listener); | |||
} | |||
@@ -208,6 +183,16 @@ public abstract class AbstractTextField extends AbstractComponent | |||
} | |||
} | |||
@Override | |||
public void writeDesign(Element design, DesignContext designContext) { | |||
super.writeDesign(design, designContext); | |||
AbstractTextField def = (AbstractTextField) designContext | |||
.getDefaultInstance(this); | |||
Attributes attr = design.attributes(); | |||
DesignAttributeHandler.writeAttribute("maxlength", attr, getMaxLength(), | |||
def.getMaxLength(), Integer.class); | |||
} | |||
@Override | |||
protected Collection<String> getCustomAttributes() { | |||
Collection<String> customAttributes = super.getCustomAttributes(); | |||
@@ -219,12 +204,22 @@ public abstract class AbstractTextField extends AbstractComponent | |||
} | |||
@Override | |||
public void writeDesign(Element design, DesignContext designContext) { | |||
super.writeDesign(design, designContext); | |||
AbstractTextField def = (AbstractTextField) designContext | |||
.getDefaultInstance(this); | |||
Attributes attr = design.attributes(); | |||
DesignAttributeHandler.writeAttribute("maxlength", attr, getMaxLength(), | |||
def.getMaxLength(), Integer.class); | |||
protected TextFieldState getState() { | |||
return (TextFieldState) super.getState(); | |||
} | |||
@Override | |||
protected TextFieldState getState(boolean markAsDirty) { | |||
return (TextFieldState) super.getState(markAsDirty); | |||
} | |||
@Override | |||
protected void doSetValue(String value) { | |||
getState().text = value; | |||
} | |||
@Override | |||
protected TextChange createValueChange(boolean userOriginated) { | |||
return new TextChange(userOriginated); | |||
} | |||
} |
@@ -26,12 +26,10 @@ import com.vaadin.shared.ui.checkbox.CheckBoxServerRpc; | |||
import com.vaadin.shared.ui.checkbox.CheckBoxState; | |||
import com.vaadin.tokka.event.EventListener; | |||
import com.vaadin.tokka.event.Registration; | |||
import com.vaadin.tokka.ui.components.HasValue; | |||
import com.vaadin.ui.AbstractComponent; | |||
import com.vaadin.ui.declarative.DesignAttributeHandler; | |||
import com.vaadin.ui.declarative.DesignContext; | |||
public class CheckBox extends AbstractComponent implements HasValue<Boolean> { | |||
public class CheckBox extends AbstractField<Boolean> { | |||
public class StateChange extends ValueChange<Boolean> { | |||
public StateChange(boolean userOriginated) { | |||
@@ -106,23 +104,8 @@ public class CheckBox extends AbstractComponent implements HasValue<Boolean> { | |||
} | |||
@Override | |||
public void setValue(Boolean value) { | |||
setValue(value, false); | |||
} | |||
protected void setValue(Boolean value, boolean userOriginated) { | |||
if (isReadOnly() && userOriginated) { | |||
return; | |||
} | |||
if (value == getValue()) { | |||
return; | |||
} | |||
getState(!userOriginated).checked = value; | |||
fireEvent(new StateChange(userOriginated)); | |||
} | |||
@Override | |||
public Registration addValueChangeListener(EventListener<ValueChange<Boolean>> listener) { | |||
public Registration addValueChangeListener( | |||
EventListener<ValueChange<Boolean>> listener) { | |||
return addListener(StateChange.class, listener); | |||
} | |||
@@ -131,22 +114,6 @@ public class CheckBox extends AbstractComponent implements HasValue<Boolean> { | |||
return getState(false).checked; | |||
} | |||
@Override | |||
protected CheckBoxState getState() { | |||
return (CheckBoxState) super.getState(); | |||
} | |||
@Override | |||
protected CheckBoxState getState(boolean markAsDirty) { | |||
return (CheckBoxState) super.getState(markAsDirty); | |||
} | |||
/* | |||
* (non-Javadoc) | |||
* | |||
* @see com.vaadin.ui.AbstractField#readDesign(org.jsoup.nodes.Element, | |||
* com.vaadin.ui.declarative.DesignContext) | |||
*/ | |||
@Override | |||
public void readDesign(Element design, DesignContext designContext) { | |||
super.readDesign(design, designContext); | |||
@@ -156,12 +123,6 @@ public class CheckBox extends AbstractComponent implements HasValue<Boolean> { | |||
} | |||
} | |||
/* | |||
* (non-Javadoc) | |||
* | |||
* @see com.vaadin.ui.AbstractField#writeDesign(org.jsoup.nodes.Element, | |||
* com.vaadin.ui.declarative.DesignContext) | |||
*/ | |||
@Override | |||
public void writeDesign(Element design, DesignContext designContext) { | |||
super.writeDesign(design, designContext); | |||
@@ -171,15 +132,30 @@ public class CheckBox extends AbstractComponent implements HasValue<Boolean> { | |||
def.getValue(), Boolean.class); | |||
} | |||
/* | |||
* (non-Javadoc) | |||
* | |||
* @see com.vaadin.ui.AbstractField#getCustomAttributes() | |||
*/ | |||
@Override | |||
protected Collection<String> getCustomAttributes() { | |||
Collection<String> attributes = super.getCustomAttributes(); | |||
attributes.add("checked"); | |||
return attributes; | |||
} | |||
@Override | |||
protected CheckBoxState getState() { | |||
return (CheckBoxState) super.getState(); | |||
} | |||
@Override | |||
protected CheckBoxState getState(boolean markAsDirty) { | |||
return (CheckBoxState) super.getState(markAsDirty); | |||
} | |||
@Override | |||
protected void doSetValue(Boolean value) { | |||
getState().checked = value; | |||
} | |||
@Override | |||
protected StateChange createValueChange(boolean userOriginated) { | |||
return new StateChange(userOriginated); | |||
} | |||
} |
@@ -27,8 +27,6 @@ import com.vaadin.shared.tokka.ui.components.fields.DateFieldServerRpc; | |||
import com.vaadin.shared.tokka.ui.components.fields.DateFieldState; | |||
import com.vaadin.tokka.event.EventListener; | |||
import com.vaadin.tokka.event.Registration; | |||
import com.vaadin.tokka.ui.components.HasValue; | |||
import com.vaadin.ui.AbstractComponent; | |||
import com.vaadin.ui.declarative.DesignContext; | |||
/** | |||
@@ -36,15 +34,14 @@ import com.vaadin.ui.declarative.DesignContext; | |||
* | |||
* @author Vaadin Ltd. | |||
*/ | |||
public class DateField extends AbstractComponent | |||
implements HasValue<LocalDate> { | |||
public class DateField extends AbstractField<LocalDate> { | |||
private static final DateTimeFormatter FORMATTER = DateTimeFormatter | |||
.ofPattern("dd-MM-uuuu"); | |||
public static class DateChange extends ValueChange<LocalDate> { | |||
protected DateChange(DateField source, boolean userOriginated) { | |||
super(source, userOriginated); | |||
public class DateChange extends ValueChange<LocalDate> { | |||
protected DateChange(boolean userOriginated) { | |||
super(DateField.this, userOriginated); | |||
} | |||
} | |||
@@ -63,46 +60,47 @@ public class DateField extends AbstractComponent | |||
@Override | |||
public void setDate(String value) { | |||
if (!isReadOnly()) { | |||
LocalDate localDate = FORMATTER.parse(value, | |||
TemporalQueries.localDate()); | |||
setValue(localDate); | |||
fireEvent(new DateChange(DateField.this, true)); | |||
} | |||
LocalDate localDate = FORMATTER.parse(value, | |||
TemporalQueries.localDate()); | |||
setValue(localDate, true); | |||
} | |||
}); | |||
} | |||
@Override | |||
protected DateFieldState getState() { | |||
return (DateFieldState) super.getState(); | |||
public LocalDate getValue() { | |||
DateFieldState state = getState(false); | |||
return FORMATTER.parse(state.date, LocalDate::from); | |||
} | |||
@Override | |||
protected DateFieldState getState(boolean markAsDirty) { | |||
return (DateFieldState) super.getState(markAsDirty); | |||
public Registration addValueChangeListener( | |||
EventListener<ValueChange<LocalDate>> listener) { | |||
return addListener(DateChange.class, listener); | |||
} | |||
@Override | |||
public void setValue(LocalDate date) { | |||
DateFieldState state = getState(); | |||
state.value = date.format(FORMATTER); | |||
public void readDesign(Element design, DesignContext designContext) { | |||
super.readDesign(design, designContext); | |||
} | |||
@Override | |||
public LocalDate getValue() { | |||
DateFieldState state = getState(false); | |||
return FORMATTER.parse(state.value, TemporalQueries.localDate()); | |||
protected DateFieldState getState() { | |||
return (DateFieldState) super.getState(); | |||
} | |||
@Override | |||
public Registration addValueChangeListener( | |||
EventListener<ValueChange<LocalDate>> listener) { | |||
return addListener(DateChange.class, listener); | |||
protected DateFieldState getState(boolean markAsDirty) { | |||
return (DateFieldState) super.getState(markAsDirty); | |||
} | |||
@Override | |||
public void readDesign(Element design, DesignContext designContext) { | |||
super.readDesign(design, designContext); | |||
protected void doSetValue(LocalDate value) { | |||
getState().date = value.format(FORMATTER); | |||
} | |||
@Override | |||
protected DateChange createValueChange(boolean userOriginated) { | |||
return new DateChange(userOriginated); | |||
} | |||
} |
@@ -15,19 +15,19 @@ | |||
*/ | |||
package com.vaadin.shared.tokka.ui.components.fields; | |||
import com.vaadin.shared.AbstractFieldState; | |||
import com.vaadin.shared.AbstractComponentState; | |||
import com.vaadin.shared.annotations.NoLayout; | |||
public class DateFieldState extends AbstractFieldState { | |||
public class DateFieldState extends AbstractComponentState { | |||
{ | |||
primaryStyleName = "v-datefield"; | |||
} | |||
/* | |||
* Year field | |||
/** | |||
* The datefield value. | |||
*/ | |||
@NoLayout | |||
public String value; | |||
public String date; | |||
/** | |||
* The prompt to display in an empty field. Null when disabled. |
@@ -0,0 +1,31 @@ | |||
/* | |||
* Copyright 2000-2014 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.shared.ui.components.fields; | |||
import com.vaadin.shared.AbstractComponentState; | |||
import com.vaadin.shared.annotations.NoLayout; | |||
public class CheckBoxState extends AbstractComponentState { | |||
{ | |||
primaryStyleName = "v-checkbox"; | |||
} | |||
/** | |||
* The checkbox value. | |||
*/ | |||
@NoLayout | |||
public boolean checked = false; | |||
} |