I have this nested Combobox, that whenever I selected something from the parent Combobox, the items from the child Combobox changes. At first try, it performs exactly what I want it to be. But when I change the selected value of the parent Combobox, the child Combobox double its action.
For example, when I selected the child Combobox, it will display "Me". But whenever I change the parent and then select the child again, it will display "Me" twice, which is supposed to be only once.
Here is my code.
cdata = ComboBoxCaller.getCityMun("PH-NCR");
cmbCit.setItems(cdata);
cmbCit.setConverter(new StringConverter<City_Municipality>() {
@Override
public String toString(City_Municipality object) {
return object.getCityName();
}
@Override
public City_Municipality fromString(String string) {
return cmbCit.getItems().stream().filter(ap -> ap.getCityName().equals(string)).findFirst().orElse(null);
}
});
pdata = ComboBoxCaller.getProvince();
cmbProv.setItems(pdata);
cmbProv.setConverter(new StringConverter<Province>() {
@Override
public String toString(Province object) {
return object.getPname();
}
@Override
public Province fromString(String string) {
return cmbProv.getItems().stream().filter(ap -> ap.getPname().equals(string)).findFirst().orElse(null);
}
});
cmbProv.valueProperty().addListener((ObservableValue<? extends Province> obs, Province oldval, Province newval) -> {
if (newval != null) {
System.out.println("Selected: " + newval.getPname() + ". ID: " + newval.getPcode());
prov_nm = newval.getPname();
// Setting up list of Cities and Municipality
cdata = ComboBoxCaller.getCityMun(newval.getPcode());
cmbCit.setItems(cdata);
cmbCit.setConverter(new StringConverter<City_Municipality>() {
@Override
public String toString(City_Municipality object) {
return object.getCityName();
}
@Override
public City_Municipality fromString(String string) {
return cmbCit.getItems().stream().filter(ap -> ap.getCityName().equals(string)).findFirst().orElse(null);
}
});
// this is where the bug/error occurs
cmbCit.valueProperty().addListener((ObservableValue<? extends City_Municipality> option, City_Municipality old, City_Municipality newVal) -> {
if (newVal != null) {
city_nm = newVal.getCityName();
cit_id = newVal.getPkCit();
System.out.println("City: " + city_nm + " City ID: " + cit_id);
isDisable(false); // disable
//Setting up list of Sub-Municipalities
smdata = ComboBoxCaller.getSubMun(newVal.getPkCit());
cmbSubMun.setItems(smdata);
cmbSubMun.setConverter(new StringConverter<Sub_Municipality>() {
@Override
public String toString(Sub_Municipality object) {
return object.getSub_mun();
}
@Override
public Sub_Municipality fromString(String string) {
return cmbSubMun.getItems().stream().filter(ap -> ap.getSub_mun().equals(string)).findFirst().orElse(null);
}
});
cmbSubMun.valueProperty().addListener((ObservableValue<? extends Sub_Municipality> opt, Sub_Municipality od, Sub_Municipality nw) -> {
if (nw != null) {
sub_vil = nw.getSub_mun();
subMun = nw.getSub_mun();
}
});
//Setting up list of Subdivisions and Village
sdata = ComboBoxCaller.getSubVil(newVal.getPkCit());
cmbSub.setItems(sdata);
cmbSub.setConverter(new StringConverter<Subdivision_Village>() {
@Override
public String toString(Subdivision_Village object) {
return object.getSub_vil();
}
@Override
public Subdivision_Village fromString(String string) {
return cmbSub.getItems().stream().filter(ap -> ap.getSub_vil().equals(string)).findFirst().orElse(null);
}
});
cmbSub.valueProperty().addListener((ObservableValue<? extends Subdivision_Village> opt, Subdivision_Village od, Subdivision_Village nw) -> {
if (nw != null) {
sub_vil = nw.getSub_vil();
}
});
} else {
isDisable(true);
}
});
}
});
the bug/error, occurred on cmbCit
, that whenever I change the selected value of cmbProv
, the items of cmbCit
changes BUT, whenever I select an item from cmbCit
, it will perform twice.
I see that you are adding a listener for cmbCit.valueProperty()
inside another listener cmbProv.valueProperty()
). Be very careful with this kind of implementation because it may raise problems : in your case, the more you will select an item in cmbProv
, the more you will collect listeners for cmbCit.valueProperty()
. You have to remove your listener each time you invoke cmbCit.valueProperty()
to make sure you won't have your procedure executed several times at once.