有没有办法在可编辑的 Vaadin 8 网格中设置验证和编辑长值



>我有一个Vaadin 8网格,我想在其中将一列设置为可编辑。为此,我有Food.calories很长的地方(是的,在这种情况下它可能是一个 int,但请记住这是一个示例,我的特定用例需要很长(:

Binder<Food> binder = foodGrid.getEditor().getBinder();
TextField caloriesTextField = new TextField();
binder.forField(caloriesTextField)
.withValidator(CustomCaloryValidator::isValidValue, "Must be valid a positive amount")
.withConverter(new StringToCaloriesConverter("Must be an integer"))
.bind(Food::getCalories, Food::setCalories);
// This line fails with the error because the types do not match.
foodGrid.addColumn(Food::getCalories, new NumberRenderer(myNumberFormat))
.setEditorComponent(new TextField(), Food::setCalories);

不幸的是,这不起作用,并且有以下错误:

类型参数"C">

的推断类型"C"不在其边界内;应实现"com.vaadin.data.HasValue">

我到处找,除了简单的编辑之外,找不到任何例子。演示采样器确实有一个使用滑块的更复杂的示例,但我无法弄清楚如何从该示例中推断......

我理解错误,它试图将长篇映射到字符串。但是我找不到将转换器添加到 addColumn 以使其工作的方法......

首先,主要问题是 Binder 没有指定泛型类型,它需要:

Binder<Food> binder = foodGrid.getEditor().getBinder();

而不是:

Binder binder = foodGrid.getEditor().getBinder();

话虽如此,还有其他几个陷阱。首先,当您执行forField()时,您需要跟踪该绑定,以便以后能够使用列进行设置。这对我来说根本不清楚。具体而言,您需要:

Binder.Binding<Food, Long> caloriesBinder = binder.forField(caloriesTextField)
.withValidator(CustomCaloryValidator::isValidValue, "Must be valid a positive amount")
.withConverter(new StringToCaloriesConverter("Must be an integer"))
.bind(Food::getCalories, Food::setCalories);

我不是 100% 确定 caloriesBinder,因为我的代码不同,这是一个例子,但你需要这种绑定。然后,您采用该绑定并执行以下操作:

foodGrid.getColumn("calories").setEditorBinding(caloriesBinding);

这允许正确的编辑器工作。这是在文档中,但示例非常简单,所以我错过了。

根据您显示的内容,下一步非常重要,是添加一个渲染器,否则您可能会遇到一些奇怪的问题。例如,如果您使用 long 来存储货币,则需要将其转换为显示货币金额。同样,如果您使用的是日期,那么您可能还想设置其格式。然后,您需要添加渲染器。我能找到如何在没有编译错误(不匹配类型(的情况下做到这一点的唯一方法是:

((Grid.Column<Food, Long>)foodGrid.getColumn("calories")).setRenderer(new CaloriesRenderer());

为了完整起见,您需要通过以下方式启用编辑器:

foodGrid.getEditor().setEnabled(true);

最后,如果表是较大 Bean 的一部分,那么您需要调用foodGrid.setItems(),您不能仅仅依赖binder.readBean(),因为它不能接受列表。因此,例如,如果豆子不是食物,而是由多种成分组成的膳食,那么你就不能做binder.readBean(meal)也不能做binder.readBean(meal.getIngredients)即使你可以为其余的形式做binder.readBean(meal)。我能让它工作的唯一方法是:

binder.readBean(meal);
foodGrid.setItems(meal.getIngredients);

最新更新