1

我有一个 Vaadin 8 Grid,我想在其中将一列设置为可编辑。为此,我有 where Food.caloriesis a long (是的,在这种情况下它可能是 int 但请记住,这是一个示例,我的特定用例需要 long):

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'

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

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

4

1 回答 1

0

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

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

并不是:

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

话虽如此,还有其他几个问题。首先,当您执行 a 时,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% 确定卡路里绑定器,因为我的代码不同,这是一个示例,但您需要该绑定。然后,您使用该绑定并执行以下操作:

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

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

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

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

为了完整起见,您需要启用编辑器:

foodGrid.getEditor().setEnabled(true);

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

binder.readBean(meal);
foodGrid.setItems(meal.getIngredients);
于 2017-08-18T21:30:49.797 回答