我有一个Vaadin 8 Grid,我想将一列设置为可编辑。为此,我有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'
我随处可见,找不到任何简单编辑以外的例子。 demo sampler确实有一个使用滑块的更复杂的例子,但我无法弄清楚如何从该示例中推断......
我理解错误,它正在尝试将long映射到String。但是我找不到一种方法来将转换器添加到addColumn以使其工作......
答案 0 :(得分:0)
首先,主要问题是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);
我对caloriesBinder并不是100%肯定,因为我的代码不同,这是一个例子,但是你需要那个绑定。然后你接受绑定并执行:
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);
其余的形式。我能让它发挥作用的唯一方法就是:
build.gradle