经过几个小时的寻找答案,我终于放弃了。
我有一个带有以下ComboBox的FXML表单:
<ComboBox fx:id="cboTipo" disable="true" prefWidth="247.0" promptText="Tipo de obra..." GridPane.columnIndex="1" GridPane.rowIndex="2" />
将其注入JavaFX控制器类中:
@FXML
public ComboBox<Tobra> cboTipo;
该组合显示了使用Eclipselink 2.7和JPA 2.2从嵌入式H2数据库加载的Tobra列表(代表:西班牙人Tipo de Obra)。
我没有向用户显示Tobra.toString的值,而是在初始化时设置了一个转换器:
@Override
public void initialize(URL url, ResourceBundle rb) {
...
Objects.requireNonNull(cboTipo, "cboTipo not injected");
...
cboTipo.setConverter(new StringConverter<Tobra>() {
@Override
public String toString(Tobra object) {
return object.getCod() + ": " + object.getNombre();
}
@Override
public Tobra fromString(String string) {
return new Tobra(string);
}
});
...
}
我有一个实现
Task<List<Tobra>>
的内部类,因此我可以在后台加载数据。然后,就成功了:task.setOnSucceeded(evt ->
cboTipo.setItems(FXCollections.observableArrayList(task.getValue()))
);
当然,当显示表单时,我在线程内运行任务:
new Thread(task).start();
在测试代码之前,一切似乎都可以正常工作。不管我单击哪个值,总是将所选值重置为第一项。我试图从代码中强制使用某些值,并且该值显示在组合框中,但是当用户单击组合以选择另一个值时,再次将所选值重置为“第一项”。
仅当使用带有类型参数的ComboBox时,才会发生此行为。当我创建不带类型参数的组合框,然后添加字符串值时,如下所示:
cboTipo.getItems().clear();
cboTipo.getItems().addAll(
tobraList.stream().map(x
-> x.getCod() + ": " + x.getNombre())
.toArray());
一切正常。
因此,我尝试使用POJO Tobra进行相同的操作而不映射到字符串:
cboTipo.getItems().clear();
cboTipo.getItems().addAll(tobraList);
但是问题再次出现。我也尝试过声明不带类型参数的
ComboBox cboTipo
,但这都不起作用。我的POJO Tobra以这种方式覆盖equals方法:
@Override
public boolean equals(Object object) {
if (!(object instanceof Tobra)) {
return false;
}
var other = (Tobra) object;
return ((this.cod == null && other.cod != null)
|| (this.cod != null && !this.cod.equals(other.cod)));
}
我究竟做错了什么?
PS:
我还尝试按照以下建议设置自己的电池工厂:
Javafx combobox with custom object displays object address though custom cell factory is used
并尝试对其进行调试,我意识到问题不在于组件的呈现,因为ComboBox的value属性在选择后永远不会更新。
最佳答案
您的equals()
方法很奇怪。
return ((this.cod == null && other.cod != null)
|| (this.cod != null && !this.cod.equals(other.cod)));
让我们分手吧。第1部分:
(this.cod == null && other.cod != null)
如果此
cod
的Tobra
是null
,而另一个cod
的Tobra
不是null
,则此部分是true
。现在,发生这种情况时,整个表达式将返回
true
,因为您有一个||
运算符。让我们看第二部分。
(this.cod != null && !this.cod.equals(other.cod))
如果此
cod
的Tobra
不是null
,而另一个cod
的Tobra
不相等,则此部分为true
。再次看起来相反。
您很可能需要
!
整个表达式。或者,您可以使用Objects.equals(this.cod, other.cod)
,它会为您检查null。最后,请确保您还覆盖了
hashCode()
并返回了不会破坏equals()
合同的正确值。阅读Javadoc以获得更多详细信息。