5

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

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

验证应该是动态的(在你输入时),如果输入被验证为假,应该显示一个红色的小感叹号,并且工具提示应该说“只允许整数!”。为了能够显示这些感叹号并进行动态验证,我需要使用一个每 200 毫秒侦听一次 textChanges 的包装器。

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

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

createField 方法:

@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
}
4

2 回答 2

9

您可以在 TextField 中添加一个转换器,将字符串转换为整数:

tField.setConverter(new StringToIntegerConverter());
tField.addValidator(new IntegerRangeValidator("Only Integers allowed!", 1, 150));
于 2014-01-18T13:51:18.053 回答
3

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

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;
    }

}
于 2013-11-08T15:19:30.847 回答