After hours searching for an answer, finally I give up on this. I have an FXML form with the following ComboBox:
<ComboBox fx:id="cboTipo" disable="true" prefWidth="247.0" promptText="Tipo de obra..." GridPane.columnIndex="1" GridPane.rowIndex="2" />
Which is injected in a JavaFX controller class:
@FXML
public ComboBox<Tobra> cboTipo;
The combo shows a list of Tobra (stands for: Tipo de Obra in spanish) loaded from an embedded H2 database using Eclipselink 2.7 and JPA 2.2.
I don't show to the user the value of Tobra.toString, instead I set a converter in the initialization:
@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);
}
});
...
}
I have an inner class which implements Task<List<Tobra>>
So I can load the data in background. Then, on succeeded:
task.setOnSucceeded(evt ->
cboTipo.setItems(FXCollections.observableArrayList(task.getValue()))
);
Of course, when showing the form I run the task inside a Thread:
new Thread(task).start();
Everything seems to work fine until the code is tested. No matters on what value I click, ALWAYS the selected value resets to the first item. I've tried to force some value from the code, and it shows up in the combobox, but when user clicks the combo to choose another value, again the selected value is reset to "first item". This behavior only occurs when using a ComboBox with type parameters. When I create the combobox without type parameter, and then I add String values, something like this:
cboTipo.getItems().clear();
cboTipo.getItems().addAll(
tobraList.stream().map(x
-> x.getCod() + ": " + x.getNombre())
.toArray());
Everything works fine.
So I've tried doing the same with my POJO Tobra without mapping to string:
cboTipo.getItems().clear();
cboTipo.getItems().addAll(tobraList);
But the issue reappears. I've also tried declaring ComboBox cboTipo
without type parameter but it neither works.
My POJO Tobra, overrides the equals method this way:
@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)));
}
What am I doing wrong?
PS: I also tried setting up my own cell factory as suggested in: Javafx combobox with custom object displays object address though custom cell factory is used
And trying and debugging it I realized that the problem isn't the rendering of the component because the value property of ComboBox never gets updated after selection.