Vaadin 表字段中未显示验证图标

Vaadin 表字段中未显示验证图标,vaadin,vaadin7,Vaadin,Vaadin7,当我进入表格的编辑模式时,我希望当用户超出任何验证限制时,数据验证感叹号图标(!)立即显示。 首先,有几个注意事项: 我使用的是Vaadin 7,所以很遗憾,Bean验证插件无法工作 数据验证按预期工作 现在,我有了一个完美的工作台,我正在使用BeanItemContainer将我的个人豆子放在里面 表和TableFieldFactory的代码如下所示: table.setContainerDataSource(buildContainer()); table.setTableFieldFa

当我进入表格的编辑模式时,我希望当用户超出任何验证限制时,数据验证感叹号图标(!)立即显示。

首先,有几个注意事项:

  • 我使用的是Vaadin 7,所以很遗憾,Bean验证插件无法工作
  • 数据验证按预期工作
现在,我有了一个完美的工作台,我正在使用BeanItemContainer将我的个人豆子放在里面

表和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键或模糊/取消聚焦该字段时,不会显示任何错误指示。我得把鼠标移到田野上看看有什么不对劲

我的问题是双重的

  • 当字段为空时,如何使感叹号图标出现 无效的(这适用于不在表中的普通文本字段)
  • 有没有办法从无效字段中获得即时响应 (显示图标)(即,在键入5个字符后, 无需按enter键或模糊/取消聚焦 问题)
  • 如果我能回答这两个问题就太好了!=)

    提前谢谢

  • 标题、必填指示符(红色星号)和最重要的错误指示符(感叹号)实际上是由包含组件的布局提供的,而不是组件本身。当可编辑组件显示在表格中时,它们将显示,而不显示布局-这就是为什么不显示错误指示器的原因

    如果我试图使这个圆成正方形,我会考虑创建一个CustomField作为可编辑字段的包装器-当包装的/委托字段无效时,在该CustomField中显示一个错误指示器。我没有尝试过这个——我根本没有在表中使用可编辑字段——但应该很容易做到

  • 在FieldFactory中的字段中添加,并在侦听器中调用field.validate()。但是请注意,除非在侦听器中执行field.setValue(event.getText())操作,否则该字段的.getValue()值通常在模糊/取消焦点之前不会更改,因此验证程序将验证旧值。有关更多详细信息,请参见Vaadin论坛

  • 这是我为验证包装器准备的东西,而不是尝试使用它。您将看到initComponent只是返回FormLayout中的字段,该字段应提供您正在查找的图标。(您可能需要从ValidatingWrapper到delegate的方法比我的多,但快速查看表明这可能就足够了。)

    然后将字段包装到tableFieldFactory中(第二个代码块)


    我不确定如何创建包装器,因为我正试图在TableFieldFactory的createField方法中实现这一点。有什么建议吗?我不熟悉FormLayout。解释得很好!它似乎工作得很好。方法textChange的调用在超出边界时引发InvalidValueException。我想我所要做的就是抓住那个错误,一切都会好起来的。非常感谢,查尔斯!效果很好,但是:在TreeTable(prabbly)中展开/折叠项目的速度非常慢,并且选择工作不正常(单击后某些行未被选中)。
    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);
      }
    });