如何使用包装器从表中的TextField验证整数

时间:2013-11-06 15:15:27

标签: vaadin vaadin7

我有一个表格,我正在使用createField()来创建字段。 在编辑模式下,用户可以在字段中输入文本。

此表中的一列只应允许Integers,因此我使用的是IntegerRangeValidator。

验证应该是动态的(如你所知),如果输入验证为false,则应显示一个小的红色感叹号,工具提示应该说“仅允许整数!”。 为了能够显示这些惊叹号并进行动态验证,我需要使用一个每200ms监听textChanges的包装器。

问题是TextField返回一个String,因此验证器将所有内容解释为字符串,即使用户在字段中键入了一个整数。

在Vaadin 7中 - 当在包装器中的覆盖textChange方法中执行验证时,如何验证表内的TextField中的整数?

createField-method:

@Override
public Field<?> createField(Container container, Object itemId, Object propertyId, com.vaadin.ui.Component uiContext) {

    TextField tField = null;

    tField = (TextField) super.createField(container, itemId, propertyId, uiContext);
    tField.setBuffered(true);
    addFieldListeners(tField);

    if (propertyId.equals("age") {
        tField.setRequired(true);
        tField.setRequiredError("This field is required!");
        // tField.setConverter(new StringToIntegerConverter()); <-- I also tried this, without success
        tField.addValidator(new IntegerRangeValidator("Only Integers allowed!", 1, 150));
        @SuppressWarnings({ "unchecked", "rawtypes" })
        TableDataValidatingWrapper<TextField> wField = new TableDataValidatingWrapper(tField);
        return wField;
    } else {
        return null;
    }
}

包装器:

public class TableDataValidatingWrapper<T> extends CustomField<T> {

    private static final long serialVersionUID = 1L;
    protected Field<T> delegate;

    public TableDataValidatingWrapper(final Field<T> delegate) {
        this.delegate = delegate;

        if (delegate instanceof TextField) {
            final TextField textField = (TextField) delegate;
            textField.setTextChangeEventMode(AbstractTextField.TextChangeEventMode.TIMEOUT);
            textField.setTextChangeTimeout(200);

            textField.setCaption("");

            textField.addTextChangeListener(new FieldEvents.TextChangeListener() {

                private static final long serialVersionUID = 1L;

                @Override
                public void textChange(FieldEvents.TextChangeEvent event) {
                    try {
                        textField.setValue(event.getText());
                        textField.validate();
                    } catch (EmptyValueException e) {
                        System.out.println("Caught exception " + e);
                    } catch (InvalidValueException e) {
                        System.out.println("Caught exception " + e);
                    } catch (Exception e) {
                        System.out.println("Caught unknown exception " + e);
                    }
                }
            });
        }
    }

    // ... some other overridden methods
}

2 个答案:

答案 0 :(得分:9)

您可以将转换器添加到TextField,将字符串转换为整数:

tField.setConverter(new StringToIntegerConverter());
tField.addValidator(new IntegerRangeValidator("Only Integers allowed!", 1, 150));

答案 1 :(得分:3)

我通过使用我自己的CustomIntegerRangeValidator来解决这个问题,因为String字段应该被验证为整数,如下所示:

public class CustomIntegerRangeValidator extends AbstractValidator<String> {

    private static final long serialVersionUID = 1L;

    private IntegerRangeValidator integerRangeValidator;

    public CustomIntegerRangeValidator(String errorMessage, Integer minValue, Integer maxValue) {
        super(errorMessage);
        this.integerRangeValidator = new IntegerRangeValidator(errorMessage, minValue, maxValue);
    }

    @Override
    protected boolean isValidValue(String value) {
        try {
            Integer result = Integer.parseInt(value);
            integerRangeValidator.validate(result);
            return true;
        } catch (NumberFormatException nfe) {
            // TODO: handle exception
            System.out.println("Cannot be parsed as Integer: " + nfe);
            return false;
        } catch (Exception e) {
            // TODO: handle exception
            System.out.println("Unknown exception: " + e);
            return false;
        }

    }

    @Override
    public Class<String> getType() {
        return String.class;
    }

}