Проверка Vaadin Bean для таблицы

Когда я вхожу в режим редактирования своей таблицы, я хочу, чтобы данные проверялись во всех полях этой таблицы.

Сначала пара замечаний:

  • Я использую Vaadin 7, поэтому дополнение Bean Validation, к сожалению, не будет работать.
  • Я знаю, что реализация JSR-303 работает, потому что я без проблем пытался добавить BeanValidator в TextField.

Теперь у меня есть прекрасно работающая таблица, для которой я использую BeanItemContainer, чтобы хранить внутри bean-компоненты Person.

Компонент Person выглядит следующим образом:

public class Person {

    @Size(min = 5, max = 50)
    private String firstName;

    @Size(min = 5, max = 50)
    private String lastName;

    @Min(0)
    @Max(2000)
    private int description;

    ... getters + setters...
}

Компоненты Person добавляются в BeanItemContainer, который, в свою очередь, устанавливается в источник данных контейнера с помощью setContainerDataSource().

BeanValidator был добавлен в таблицу следующим образом:

table.addValidator(new BeanValidator(Person.class, "firstName"));

Когда я запускаю приложение, у меня возникают две проблемы:

  1. Когда я запускаю приложение, таблица отображается так, как предполагалось. Однако, когда я редактирую поля и устанавливаю для одного из полей firstName, скажем, "abc" - ошибка проверки не отображается, и значение принимается Как я должен заставить BeanValidator работать со всеми полями моих таблиц ?

  2. #P9# <блочная цитата> #P10#

Пожалуйста посоветуй

Спасибо!


person Roger    schedule 29.07.2013    source источник
comment
Полезно будет посмотреть: а) объявление поля Person.firstName, б) проблемные значения этого поля   -  person default locale    schedule 29.07.2013
comment
Класс Person теперь добавлен к моему исходному вопросу. Также нашел причину одной проблемы (исключение), но она все равно не работает. Я обновил свой исходный вопрос соответственно.   -  person Roger    schedule 29.07.2013


Ответы (1)


Вам нужно будет добавить валидаторы в сами редактируемые поля, а не в таблицу. (Таблица сама по себе является полем => Валидатор из table.addValidator проверяет значение Таблицы => значением таблицы является выбранный элемент(ы) => BeanValidator терпит неудачу)

Вы можете добавить валидаторы в поля, используя пользовательскую фабрику TableFieldFactory в таблице. Вот очень простой одноразовый пример для этого сценария - ясно, что если вам нужно сделать это с большим количеством разных bean-компонентов/таблиц, стоит создать более общую/настраиваемую фабрику.

  table.setTableFieldFactory(new DefaultFieldFactory() {
  @Override
  public Field<?> createField(Item item, Object propertyId, Component uiContext) {
    Field<?> field = super.createField(item, propertyId, uiContext);
    if (propertyId.equals("firstName")) {
      field.addValidator(new BeanValidator(Person.class, "firstName"));
    }
    if (propertyId.equals("lastName")) {
      field.addValidator(new BeanValidator(Person.class, "lastName"));
    }
    if (propertyId.equals("description")) {
      field.addValidator(new BeanValidator(Person.class, "description"));
    }
    return field;
  }
person Charles Anthony    schedule 29.07.2013
comment
Конечно. Это звучит вполне очевидно. Я попробую как можно скорее и вернусь с результатами. Спасибо, Чарльз! - person Roger; 29.07.2013
comment
Оно работает! Но только когда я предварительно загружаю таблицу с недопустимыми значениями (отображается красный текст, указывающий, что не так). Когда я редактирую таблицу и меняю допустимое значение на недопустимое, оно не примет его - как предполагалось, но, с другой стороны, всплывающая подсказка об ошибке проверки НЕ будет отображаться. Следующий вопрос заключается в том, почему красный восклицательный знак не отображается, но это может выходить за рамки этого вопроса. - person Roger; 29.07.2013
comment
Получил текст предупреждения сейчас. Мне пришлось сделать его AbstractField и использовать setImmediate(true). Тем не менее я должен нажать Enter в текстовом поле и навести курсор, чтобы появилась всплывающая подсказка. - person Roger; 29.07.2013
comment
К сожалению, то же решение не работает для меня: table.setTableFieldFactory(new AddBeanFieldFactory<EnumValueDescriptor>(EnumValueDescriptor.class){ @Override public Field<?> createField(Container container, final Object itemId, Object propertyId, Component uiContext) { Field<?> field = super.createField(container, itemId, propertyId, uiContext); field.addValidator(new Validator(){ @Override public void validate(Object value) throws InvalidValueException {throw new InvalidValueException("test"); }}); изменяет поведение таблицы: мне нужно установить значение дважды, чтобы установить его (в первый раз оно исчезает - person agad; 21.10.2013