Handle empty type assumptions

This commit is contained in:
Moritz Dieing 2021-03-10 20:41:40 +01:00
parent 3a0ee669d4
commit 2d6b33190c
2 changed files with 23 additions and 8 deletions

View File

@ -9,6 +9,7 @@ import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.textfield.TextField; import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.binder.Binder; import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.data.value.ValueChangeMode;
import com.vaadin.flow.i18n.LocaleChangeEvent; import com.vaadin.flow.i18n.LocaleChangeEvent;
import com.vaadin.flow.i18n.LocaleChangeObserver; import com.vaadin.flow.i18n.LocaleChangeObserver;
import edu.kit.typicalc.model.parser.TypeAssumptionParser; import edu.kit.typicalc.model.parser.TypeAssumptionParser;
@ -49,6 +50,9 @@ public class TypeAssumptionField extends HorizontalLayout implements LocaleChang
private final TextField variableInputField; private final TextField variableInputField;
private final TextField typeInputField; private final TextField typeInputField;
private final Binder<String> varBinder = new Binder<>();
private final Binder<String> typeBinder = new Binder<>();
/** /**
* Creates a new TypeAssumptionField with initial values and a callback to remove this * Creates a new TypeAssumptionField with initial values and a callback to remove this
* type assumption from the {@link TypeAssumptionsArea}. * type assumption from the {@link TypeAssumptionsArea}.
@ -81,6 +85,9 @@ public class TypeAssumptionField extends HorizontalLayout implements LocaleChang
Button deleteButton = new Button(minusIcon, event -> deleteSelf.accept(this)); Button deleteButton = new Button(minusIcon, event -> deleteSelf.accept(this));
deleteButton.setId(ASS_DELETE_BUTTON_ID); deleteButton.setId(ASS_DELETE_BUTTON_ID);
deleteButton.setTabIndex(-1); deleteButton.setTabIndex(-1);
variableInputField.addBlurListener(event -> typeBinder.validate());
typeInputField.addBlurListener(event -> varBinder.validate());
addValidatior(); addValidatior();
add(variableInputField, typeInputField, deleteButton); add(variableInputField, typeInputField, deleteButton);
setId(ASSUMPTIONS_FIELD_ID); setId(ASSUMPTIONS_FIELD_ID);
@ -93,7 +100,7 @@ public class TypeAssumptionField extends HorizontalLayout implements LocaleChang
* @return true if the variable matches the syntax, false if not * @return true if the variable matches the syntax, false if not
*/ */
protected boolean hasCorrectVariable(String variable) { protected boolean hasCorrectVariable(String variable) {
return variable.isEmpty() || TypeAssumptionParser.TYPE_NAME_PATTERN.matcher(variable).matches(); return TypeAssumptionParser.TYPE_NAME_PATTERN.matcher(variable).matches();
} }
/** /**
@ -103,18 +110,16 @@ public class TypeAssumptionField extends HorizontalLayout implements LocaleChang
* @return true if the type matches the syntax, false if not * @return true if the type matches the syntax, false if not
*/ */
protected boolean hasCorrectType(String type) { protected boolean hasCorrectType(String type) {
return type.isEmpty() || parser.parseType(parseBackType(type)).isOk(); return parser.parseType(parseBackType(type)).isOk();
} }
private void addValidatior() { private void addValidatior() {
Binder<String> varBinder = new Binder<>();
varBinder.forField(variableInputField) varBinder.forField(variableInputField)
.withValidator(this::hasCorrectVariable, StringUtils.EMPTY) .withValidator(var -> (hasCorrectVariable(var) || isEmpty()), StringUtils.EMPTY)
.bind(o -> variableInputField.getEmptyValue(), null); .bind(o -> variableInputField.getEmptyValue(), null);
variableInputField.setReadOnly(false); variableInputField.setReadOnly(false);
Binder<String> typeBinder = new Binder<>();
typeBinder.forField(typeInputField) typeBinder.forField(typeInputField)
.withValidator(this::hasCorrectType, StringUtils.EMPTY) .withValidator(type -> (hasCorrectVariable(type) || isEmpty()), StringUtils.EMPTY)
.bind(o -> typeInputField.getEmptyValue(), null); .bind(o -> typeInputField.getEmptyValue(), null);
typeInputField.setReadOnly(false); typeInputField.setReadOnly(false);
} }
@ -130,6 +135,15 @@ public class TypeAssumptionField extends HorizontalLayout implements LocaleChang
return new String(rawTypeArray); return new String(rawTypeArray);
} }
/**
* Checks if both text fields of this type assumption are empty.
*
* @return true if both text fields are empty, false if not
*/
protected boolean isEmpty() {
return getVariable().isEmpty() && getType().isEmpty();
}
/** /**
* This method is called when the dialog containing this field is reopened. Since Vaadin somehow detaches the * This method is called when the dialog containing this field is reopened. Since Vaadin somehow detaches the
* event listener, it has to be added again. * event listener, it has to be added again.

View File

@ -96,7 +96,8 @@ public class TypeAssumptionsArea extends Dialog implements LocaleChangeObserver
private void closeAction() { private void closeAction() {
for (TypeAssumptionField field : fields) { for (TypeAssumptionField field : fields) {
if (!(field.hasCorrectType(field.getType()) && field.hasCorrectVariable(field.getVariable()))) { if (!(field.hasCorrectType(field.getType()) && field.hasCorrectVariable(field.getVariable()))
&& !field.isEmpty()) {
invalidInputNotification.open(); invalidInputNotification.open();
return; return;
} }