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

Java 有没有办法在可编辑的Vaadin 8网格中设置验证和编辑长值,java,vaadin,vaadin-grid,vaadin8,Java,Vaadin,Vaadin Grid,Vaadin8,我有一个Vaadin 8网格,我想将其中一列设置为可编辑。对于这一点,我有一个whereFood.carries是一个long(是的,在本例中它可以是int,但请记住这是一个示例,我的特定用例需要一个long): Binder Binder=foodGrid.getEditor().getBinder(); TextField=new TextField(); 活页夹forField(CARROESTEXTFIELD) .withValidator(CustomCaloryValidator::

我有一个Vaadin 8网格,我想将其中一列设置为可编辑。对于这一点,我有一个where
Food.carries
是一个long(是的,在本例中它可以是int,但请记住这是一个示例,我的特定用例需要一个long):

Binder Binder=foodGrid.getEditor().getBinder();
TextField=new TextField();
活页夹forField(CARROESTEXTFIELD)
.withValidator(CustomCaloryValidator::isValidValue,“必须是有效的正值”)
.withConverter(新StringToCalories转换器(“必须是整数”))
.bind(食物::获取卡路里,食物::设置卡路里);
//此行失败并出现错误,因为类型不匹配。
addColumn(Food::getCarries,new NumberRenderer(myNumberFormat))
.setEditorComponent(新文本字段(),食品::SetCarries);
不幸的是,这不起作用,并且有以下错误:

类型参数“C”的推断类型“C”不在其范围内;应该实现'com.vaadin.data.HasValue'

我找遍了所有我能找到的地方,除了简单的编辑之外,找不到任何例子。确实有一个使用滑块的更复杂的示例,但我不知道如何从该示例推断


我理解这个错误,它试图将一个长字符串映射为一个字符串。但是,我找不到一种方法将转换器添加到addColumn以使其工作…

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

Binder<Food> 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);
这允许正确的编辑器工作。这在文档中,但示例非常简单,因此我忽略了这一点

下一步是添加渲染器,这一步非常重要,这取决于您正在显示的内容,否则您可能会遇到一些奇怪的问题。例如,如果要使用long存储货币,则需要将其转换为显示货币金额。类似地,如果您使用的是日期,那么您可能还需要格式化它。然后需要添加渲染器。我能找到如何在没有编译错误(类型不匹配)的情况下执行此操作的唯一方法是:

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

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

首先,主要问题是活页夹没有指定通用类型,需要:

Binder<Food> 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);
这允许正确的编辑器工作。这在文档中,但示例非常简单,因此我忽略了这一点

下一步是添加渲染器,这一步非常重要,这取决于您正在显示的内容,否则您可能会遇到一些奇怪的问题。例如,如果要使用long存储货币,则需要将其转换为显示货币金额。类似地,如果您使用的是日期,那么您可能还需要格式化它。然后需要添加渲染器。我能找到如何在没有编译错误(类型不匹配)的情况下执行此操作的唯一方法是:

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

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

你看过报纸了吗?在这里,您可以找到一个使用
活页夹
grid.getEditor().getBinder()
)的示例,该活页夹可用于验证和转换字段值。编译错误是由列数据类型(
Long
)之间的不匹配引起的以及编辑器组件,其值类型为
字符串
,因为它是一个
文本字段
实现
HasValue
。如果提供的编辑器组件不涉及
活页夹
,则需要一个支持
值的字段。据我所知,没有这种开箱即用的领域。但是,更好的方法是使用
活页夹
,因为您可以验证和转换。这允许在
StringToLongConverter
中使用
TextField
进行
Long
输入。我只是不知道bind()也是forField()的快捷方式。Vaadin有很好的文档,只是大多数示例都是简单的用例。文档说明了这是可能的,但示例没有说明如何实现。它使用快捷方式bind()方法。但是如果你看一下文档:他们在几乎每个例子中都使用forField()和bind()。因此,在网格编辑示例中,我没有捕捉到bind()也被称为forField(),这也不是那么简单。当我尝试它时,它仍然不起作用。它说,与表单(对象而不是字符串)相比,验证器的类型不正确,当我使用forField()尝试交换验证器和转换器行时,绑定也不起作用。命令
foodGrid.getEditor().setEnabled(true);
binder.readBean(meal);
foodGrid.setItems(meal.getIngredients);