What I'm trying to do is have a single class that maintains a static ObservableList of countries. I want to display these countries in a ComboBox. I've got this part working fine. Now, I also want to enable the user to add new countries to the list. So, there is a button beside the combo box that will show another dialog allowing entry of another country name. After the user enters the country name and clicks save, I would like the single static ObservableList to be updated with the new country and then it show up in the ComboBox. This part is not happening.
I'll show what DOES work, and what does not.
Saving a reference to the static list and updating that works. Like so:
public class CustomerController implements Initializable {
private ObservableList<Country> countryList;
@Override
public void initialize(URL url, ResourceBundle rb) {
countryList = Country.getCountryList();
comboCountry.setItems(countryList);
}
...
// Fired when clicking the "new country" button
@FXML
void handleNewCountry(ActionEvent event) {
Country country = new Country();
country.setCountry("Austria");
countryList.add(country);
}
}
This is what I would like to do, however it does not work:
public class CustomerController implements Initializable {
@FXML
private ComboBox<Country> comboCountry;
@Override
public void initialize(URL url, ResourceBundle rb) {
comboCountry.setItems(Country.getCountryList());
}
@FXML
void handleNewCountry(ActionEvent event) {
showScene("Country.fxml", "dialog.newCountry");
}
private void showScene(String sceneResource, String titleResource) {
try {
FXMLLoader loader = new FXMLLoader(
getClass().getResource(sceneResource),
resourceBundle
);
Scene scene = new Scene(loader.load());
getNewStage(resourceBundle.getString(titleResource), scene).showAndWait();
} catch (IOException e) {
e.printStackTrace();
}
}
private Stage getNewStage(String title, Scene scene) {
Stage stage = new Stage();
stage.setTitle(title);
stage.setResizable(false);
stage.setScene(scene);
stage.initOwner(rootPane.getScene().getWindow());
stage.initModality(Modality.APPLICATION_MODAL);
return stage;
}
}
The Country class:
public class Country extends BaseModel {
private int countryID;
private StringProperty country;
private static ObservableList<Country> countryList; // The static observable list
public Country() {
countryList = FXCollections.observableArrayList();
country = new SimpleStringProperty();
}
public int getCountryID() {
return countryID;
}
public void setCountryID(int countryID) {
this.countryID = countryID;
}
public StringProperty countryProperty() {
return this.country;
}
public String getCountry() {
return this.country.get();
}
public void setCountry(String country) {
this.country.set(country);
}
public boolean equals(Country country) {
if (this.getCountry().compareToIgnoreCase(country.getCountry()) != 0) {
return false;
}
return true;
}
public static ObservableList<Country> getCountryList() {
if (countryList.size() < 1) {
updateCountryList();
}
return countryList;
}
public static void updateCountryList() {
countryList.clear();
ArrayList<Country> daoList = CountryDao.listCountries();
for (Country country : daoList) {
countryList.add(country);
}
}
@Override
public String toString() {
return this.getCountry();
}
}
And the dialog for entering a new country:
public class CountryController implements Initializable {
@FXML
private TextField textCountry;
@Override
public void initialize(URL url, ResourceBundle rb) {
}
@FXML
void handleSave(ActionEvent event) {
Country country = new Country();
country.setCountry(textCountry.getText().trim());
CountryDao.insert(country); // Insert the country into the database
Country.updateCountryList(); // Update the static ObservableList
close();
}
@FXML
void handleCancel() {
close();
}
void close() {
final Stage stage = (Stage) textCountry.getScene().getWindow();
stage.close();
}
}
So, my theory is that somehow the ComboBox is creating a new instance of the ObservableList when setItems is called. I'm really not sure though. A static object should only have one instance, so updating it from anywhere should update that ComboBox. Anyone know what's up with this?