Vaadin ComboBox绑定异常,点击Grid后无法自动填充如何解决?
Vaadin ComboBox绑定后点击Grid无法自动填充值问题
问题场景
我现在找不到Vaadin ComboBox的正确绑定方法,想要实现点击Grid后自动填充ComboBox值的效果:ComboBox的选项数据来自数据库的Acception表,Grid的数据绑定的是WordAcception类。
报错信息
系统报错截图如下:
[错误截图1]
[错误截图2]
初始相关代码
WORDACCEPTION.java
public class WordAcception implements Serializable, Cloneable { private String idacception = ""; public String getIdacception() { return idacception; } public void setIdacception(String idacception) { this.idacception = idacception; } }
VISTA.java
private ComboBox<Acception> WordAcceptioncombo = new ComboBox<>("idacception"); WordAcceptioncombo.setItemLabelGenerator(Acception::getIdAcception); WordAcceptioncombo.setItems(AcceptionPersistence.getInstance().findAllIdAcception()); add(WordAcceptioncombo); wordacceptionGrid.asSingleSelect().addValueChangeListener(event -> formword.setWordAcception(wordacceptionGrid.asSingleSelect().getValue()));
WORDACCEPTIONFORM.java(初始版本)
binder.bind(WordAcceptioncombo, Acception::getIdAcception, Acception::setIdAcception); public void setWordAcception(WordAcception wordAcception) { if(wordAcception != null) { System.out.println("setWordAcception= "+wordAcception.getIdacception()); WordAcceptioncombo.setValue(wordAcception.getIdacception()); } binder.setBean(wordAcception); if (binder.getBean() == null) { setVisible(false); } else { setVisible(true); idacception.focus(); } }
ACCEPTION.java(初始版本)
public class Acception implements Serializable, Cloneable { private String idAcception = ""; public String getIdAcception() { return idAcception; } public void setIdAcception(String idAcception) { this.idAcception = idAcception; } }
问题更新
因为ComboBox的选项是基于Acception类生成的,我在WordAcception类中新增了Acception类型的字段和对应的get/set方法,修改了Binder绑定逻辑,之前的报错消失了,但ComboBox还是无法自动填充。
更新后代码
ACCEPTION.java
public class Acception implements Serializable, Cloneable { private Clase clase; public Clase getClase() { return clase; } public void setClase(Clase clase) { this.clase = clase; } }
WORDACCEPTIONFORM.java(更新后绑定逻辑)
binder.bind(WordAcceptioncombo, WordAcception::getAcception, WordAcception::setAcception);
解决方案
问题根源
- 你使用的
ComboBox<Acception>泛型是Acception对象类型,初始版本直接传入String类型的ID调用setValue,类型不匹配无法匹配到选项 - 即使修改了Binder绑定逻辑,WordAcception实例中的Acception字段没有被实际赋值,或者Acception类没有正确重写
equals和hashCode方法,导致ComboBox无法匹配到对应选项
修复步骤
- 重写Acception类的equals和hashCode方法,基于idAcception字段判断对象相等,避免因为实例不是同一个对象导致匹配失败:
import java.util.Objects; public class Acception implements Serializable, Cloneable { private String idAcception = ""; private Clase clase; public String getIdAcception() { return idAcception; } public void setIdAcception(String idAcception) { this.idAcception = idAcception; } public Clase getClase() { return clase; } public void setClase(Clase clase) { this.clase = clase; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Acception acception = (Acception) o; return Objects.equals(idAcception, acception.idAcception); } @Override public int hashCode() { return Objects.hash(idAcception); } }
- 修改setWordAcception方法,根据WordAcception的idacception字段匹配对应的Acception实例,赋值给WordAcception的Acception字段,Binder会自动填充ComboBox:
public void setWordAcception(WordAcception wordAcception) { if(wordAcception != null) { System.out.println("setWordAcception= "+wordAcception.getIdacception()); // 从ComboBox已加载的选项中匹配对应ID的Acception实例 Acception matchedAcception = WordAcceptioncombo.getListDataView() .getItems() .filter(acception -> acception.getIdAcception().equals(wordAcception.getIdacception())) .findFirst() .orElse(null); wordAcception.setAcception(matchedAcception); } binder.setBean(wordAcception); setVisible(binder.getBean() != null); if (isVisible()) { idacception.focus(); } }
- 你现在的Binder绑定逻辑不需要修改,保持现有代码即可。
这样修改后,点击Grid行时就会自动匹配到对应的Acception选项,填充到ComboBox中。
内容的提问来源于stack exchange,提问作者pablo villa
相关产品推荐
相关产品推荐

