当我进入我的表的编辑模式时,我希望在用户超出任何验证限制的范围时立即显示数据验证感叹号图标(!)。 < / p>
首先,几个笔记:
现在,我有一个完美的工作表,我正在使用BeanItemContainer来保持我的Person bean。
表和TableFieldFactory的代码如下所示:
table.setContainerDataSource(buildContainer());
table.setTableFieldFactory(new TableFieldFactory() {
@Override
public Field createField(Container container, Object itemId, Object propertyId, Component uiContext) {
TextField field = (TextField) DefaultFieldFactory.get().createField(container, itemId, propertyId,
uiContext);
field.setImmediate(true);
if (propertyId.equals("firstName")) {
field.addValidator(new BeanValidator(Person.class, "firstName"));
}
return field;
}
});
Person bean如下所示:
public class Person {
@Size(min = 5, max = 50)
private String firstName;
... setters + getters...
}
问题在于,当我在firstName字段中键入内容然后按enter或blur / unfocus该字段时,不会显示任何错误指示。我必须将鼠标悬停在该字段上以查看出现问题。
我的问题是两个折叠......
如果我能回答两个问题,那就太好了! =)
提前致谢!
答案 0 :(得分:3)
标题,必需指示符(红色星号)和 - 最重要的是 - 错误指示符(感叹号)实际上由包含组件的布局提供,不组件本身。当可编辑组件显示在表格中时,它们会显示不带布局 - 这就是没有显示错误指示符的原因。
如果我试图对这个圆圈进行平方,我会考虑创建一个CustomField作为可编辑字段的包装器 - 并且当包装/委托字段变为无效时,该CustomField中会显示错误指示符。我没试过这个 - 我根本没有在表格中使用过可编辑的字段 - 但是应该很容易做到。
在FieldFactory中的字段中添加TextChangeListener,并在侦听器中调用field.validate()。但是请注意,field.getValue()值通常不会更改直到模糊/非焦点,因此验证器将验证旧值 - 除非您执行field.setValue(event.getText())在听众中。有关详细信息,请参阅Vaadin论坛上的this post。
这是我对验证包装器的意思 - 没有尝试使用它。您将看到initComponent只返回FormLayout中的字段,该字段应该为您提供您正在寻找的图标。 (您可能需要将来自ValidatingWrapper的更多方法委托给委托,但我可以快速查看这可能就足够了。)
然后将该字段包装在tableFieldFactory(第二个代码块)
中public class ValidatingWrapper<T> extends CustomField<T> {
private static final long serialVersionUID = 9208404294767862319L;
protected Field<T> delegate;
public ValidatingWrapper(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.addTextChangeListener(new FieldEvents.TextChangeListener() {
@Override
public void textChange(FieldEvents.TextChangeEvent event) {
textField.setValue(event.getText());
textField.validate();
}
});
}
}
@Override
public Class<? extends T> getType() {
return delegate.getType();
}
@Override
protected Component initContent() {
return new FormLayout(delegate);
}
@Override
public Property getPropertyDataSource() {
return delegate.getPropertyDataSource();
}
@Override
public void setPropertyDataSource(Property newDataSource) {
delegate.setPropertyDataSource(newDataSource);
}
}
table.setContainerDataSource(buildContainer());
table.setTableFieldFactory(new TableFieldFactory() {
@Override
public Field createField(Container container, Object itemId, Object propertyId, Component uiContext) {
TextField field = (TextField) DefaultFieldFactory.get().createField(container, itemId, propertyId,
uiContext);
field.setImmediate(true);
if (propertyId.equals("firstName")) {
field.addValidator(new BeanValidator(Person.class, "firstName"));
}
return ValidatingWrapper(field);
}
});