In Scene Builder, I placed a ChoiceBox and gave it an fx:id.
In the "controller" class:
@FXML ChoiceBox<UserGroup> userGroupCB;
In the "initialize()" method of the "controller", I set a StringConverter for the choice box so that it would display the "name" property of the domain object:
@FXML
protected void initialize() {
...
userGroupCB.setConverter(new StringConverter<UserGroup>() {
@Override
public String toString(UserGroup userGroup) {
return userGroup.getName();
}
@Override
public UserGroup fromString(String arg0) {
return null;
}
});
....
Prior to setting this converter, I had added a toString() method to the UserGroup and everything worked just fine without the converter. However, I really didn't want to default to using the toString() method, so I set the converter.
Boom! Crash! A ClassCastException occurred when setting the converter in the "initialize()" method. Scratch head, pull hair.
By chance, I looked at the FXML in an XML editor and discovered that Scene Builder had stubbed out an <item> list!
<ChoiceBox ... >
<items>
<FXCollections fx:factory="observableArrayList">
<String fx:value="Item 1" />
<String fx:value="Item 2" />
<String fx:value="Item 3" />
</FXCollections>
</items>
</ChoiceBox>
So, yeah, of course, unbeknownst to me, it was expecting a String and I was specifying a UserGroup in the converter! (See also the @FXML ChoiceBox<UserGroup> ivar above.) Silly me.
Why is Scene Builder stubbing out this <item> list?! There's no reason for it.
Note that it does the same thing for ComboBox.
I suppose that when I invoke "setItems()" on this choice box [this occurs outside the initialize() method because the values in the choice box are context sensitive, but always UserGroup items], but I shouldn't have to work around what shouldn't be a problem in the first place.
Does anyone else think this is unexpected behind the scenes behavior for Scene Builder?