首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >转换错误导致vaadin23 ComboBox.setValue失败

转换错误导致vaadin23 ComboBox.setValue失败
EN

Stack Overflow用户
提问于 2022-04-18 02:02:11
回答 1查看 196关注 0票数 0

我使用vaadin23在组合框中使用绑定器显示时区列表:

代码语言:javascript
复制
ComboBox<ZoneId> timezoneField = new ComboBox<>();
timezoneField.setItemLabelGenerator(zoneId -> zoneId.getId());
timezoneField.setItems(Timezones.getZones());
binder.forField(timezoneField)
                .bind("timezone");
final var registration = new Registration(member, organisation);
binder.setBean(registration);

在我尝试设置默认值之前,上面的代码似乎运行良好:

代码语言:javascript
复制
        UI.getCurrent().getPage().retrieveExtendedClientDetails(extendedClientDetails ->
            {
                int timezoneOffest = extendedClientDetails.getRawTimezoneOffset();
                var possibleZones = Conversions.timezonesFromOffset(timezoneOffest);
                if (possibleZones.size() != 0)
                {
                    // this line throws
                    this.timezoneField.setValue((ZoneId) possibleZones.get(0));
                }

            });

possibleZones返回一个ZoneId列表,但是在调试器中,它们显示为ZoneRegion。我认为这没有问题,因为ZoneRegion是一种ZoneId类型。我在调用setValue时进行强制转换,以防万一。

所以当我打电话:

代码语言:javascript
复制
this.timezoneField.setValue((ZoneId) possibleZones.get(0));

引发以下错误:

代码语言:javascript
复制
 com.vaadin.flow.data.binder.BindingException: An exception has been thrown inside binding logic for the field element [suppress-template-warning='', _inputElementValue='', _clientSideFilter='false', selectedItem='null', invalid='false', pageSize='50', itemValuePath='key', itemIdPath='key', value='1']
    at com.vaadin.flow.data.binder.Binder$BindingImpl.execute(Binder.java:1542) ~[flow-data-23.0.4.jar:23.0.4]
    at com.vaadin.flow.data.binder.Binder$BindingImpl.doConversion(Binder.java:1286) ~[flow-data-23.0.4.jar:23.0.4]
    at com.vaadin.flow.data.binder.Binder$BindingImpl.doValidation(Binder.java:1306) ~[flow-data-23.0.4.jar:23.0.4]
    at com.vaadin.flow.data.binder.Binder$BindingImpl.validate(Binder.java:1247) ~[flow-data-23.0.4.jar:23.0.4]
    at com.vaadin.flow.data.binder.Binder.lambda$doWriteIfValid$3(Binder.java:2245) ~

...

    at com.vaadin.flow.data.binder.Binder.doWriteIfValid(Binder.java:2246) ~[flow-data-23.0.4.jar:23.0.4]

....
com.vaadin.flow.component.internal.AbstractFieldSupport.setValue(AbstractFieldSupport.java:135) ~[flow-server-23.0.4.jar:23.0.4]
    at com.vaadin.flow.component.AbstractField.setValue(AbstractField.java:181) ~[flow-server-23.0.4.jar:23.0.4]
    at com.vaadin.flow.component.combobox.ComboBox.setValue(ComboBox.java:396) ~[vaadin-combo-box-flow-23.0.5.jar:?]
    at dev.onepub.ui.views.noauth.RegistrationView.lambda$4(RegistrationView.java:171) ~[classes/:?]

...

caused by:

Caused by: java.lang.ClassCastException: Cannot cast java.time.ZoneRegion to java.lang.String
    at java.lang.Class.cast(Class.java:3889) ~[?:?]
    at com.vaadin.flow.data.converter.Converter.lambda$from$957be2b0$1(Converter.java:104) ~[flow-data-23.0.4.jar:23.0.4]
    at com.vaadin.flow.data.binder.Result.of(Result.java:90) ~[flow-data-23.0.4.jar:23.0.4]
    at com.vaadin.flow.data.converter.Converter.lambda$from$b652e465$1(Converter.java:104) ~[flow-data-23.0.4.jar:23.0.4]
    at com.vaadin.flow.data.converter.Converter$1.convertToModel(Converter.java:130) ~[flow-data-23.0.4.jar:23.0.4]
    at com.vaadin.flow.data.converter.Converter$2.lambda$convertToModel$6b579330$1(Converter.java:165) ~[flow-data-23.0.4.jar:23.0.4]
    at com.vaadin.flow.data.binder.SimpleResult.flatMap(SimpleResult.java:65) ~[flow-data-23.0.4.jar:23.0.4]
    at com.vaadin.flow.data.binder.ValidationResultWrap.flatMap(ValidationResultWrap.java:67) ~[flow-data-23.0.4.jar:23.0.4]
    at com.vaadin.flow.data.converter.Converter$2.convertToModel(Converter.java:165) ~[flow-data-23.0.4.jar:23.0.4]
    at com.vaadin.flow.data.binder.Binder$BindingImpl.lambda$doConversion$0(Binder.java:1288) ~[flow-data-23.0.4.jar:23.0.4]

我注意到,转换是在抱怨将ZoneRegion转换为String。

考虑到组合框是ZoneId类型的,并且有一个ItemLabelGenerator,我不明白为什么会产生这个错误?

EN

回答 1

Stack Overflow用户

发布于 2022-04-18 21:50:00

所以答案是制造一个转换器。考虑到setValue使用的类型与组合框存储的类型相同,我仍然不理解为什么它需要一个转换器才能工作。

这里记录的是转换器:

代码语言:javascript
复制
package dev.onepub.fields.converters;

import java.time.ZoneId;

import com.vaadin.flow.data.binder.Result;
import com.vaadin.flow.data.binder.ValueContext;
import com.vaadin.flow.data.converter.Converter;

public class ZoneIdToStringConverter implements Converter<ZoneId, String>
{
    private static final long serialVersionUID = 1L;

    @Override
    public Result<String> convertToModel(ZoneId fieldValue, ValueContext context)
    {

        // Converting to the field type should always succeed,
        // so there is no support for returning an error Result.
        if (fieldValue == null)
        {
            return Result.ok(ZoneId.systemDefault().getId());
        }
        return Result.ok(fieldValue.getId());
    }

    @Override
    public ZoneId convertToPresentation(String zoneId, ValueContext context)
    {
        // Produces a converted value or an error

        // ok is a static helper method that creates a Result
        if (zoneId == null)
            return ZoneId.systemDefault();
        else
            return ZoneId.of(zoneId);

    }

}

把它叫做

代码语言:javascript
复制
ComboBox<ZoneId> timezoneField = new ComboBox<>();
timezoneField.setItemLabelGenerator(zoneId -> zoneId.getId());
timezoneField.setItems(Timezones.getZones());
binder.forField(timezoneField)
    .withConverter(new ZoneIdToStringConverter())
    .bind("timezone");
final var registration = new Registration(member, organisation);
binder.setBean(registration);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71906928

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档