有没有办法在可编辑的Vaadin 8网格

时间:2017-08-15 04:26:29

标签: java vaadin vaadin-grid vaadin8

我有一个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以使其工作......

1 个答案:

答案 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