I am using cell factory for listview with checkboxes like:
listView.setCellFactory(CheckBoxListCell.forListView(new Callback < Bean, ObservableValue < Boolean >> () {
@Override
public ObservableValue < Boolean > call(Bean item) {
BooleanProperty observable = new SimpleBooleanProperty();
observable.addListener((obs, wasSelected, isNowSelected) -> {
if (isNowSelected) {
if (!beanChoices.contains(item.toString())) {
beanChoices.add(item.toString());
observable.setValue(true);
//listView.scrollTo(listView.getItems().size() - 1);
}
} else if (wasSelected) {
if (beanChoices.contains(item.toString())) {
beanChoices.remove(item.toString());
observable.setValue(false);
}
}
});
/* [Code] which compares values with bean item string value and select observable to true for that for edit mode
but here the observer not called for beanItem that are under scrollpane of listview. But on scroll it gets called. */
return observable;
}
}));
It works fine but not for all cases.
Case: When I have say more than 10 entries, the scrollpane comes. Say I have beanChoices to be checked that are at 8 or 9 index(you have to scroll to view them).
The listener is not called for the items not visible(that are under scrollpane).
On Debug, I found that listener is called when I scroll down.
Problem: when I get checked values from beanChoices for above case, it return empty.
Detail: I have beanChoices which I need to make checked for listview items (edit mode). When I update without changing anything. (Assume that the value which is under the scrollpane of listview will be selected and added to beanChoices)
The
Callback
is used to retrieve the property for the checked state when the item is associated with a cell. The item may be removed from a cell and put in a new one at any time. This is howListView
(and similar controls likeTableView
) works.CheckBoxListCell
simply gets the checked state property every time a new item is associated with the cell.The return value is also used to set the initial state of the
CheckBox
. Since you do not properly initialize the property with the correct value the initial state is not preserved.Also note that it makes little sense to update the value of the property to the new value in the change listener. It happens anyway.
Since
BooleanProperty
is a wrapper for primitiveboolean
the possible values aretrue
andfalse
; theChangeListener
only gets called when!Objects.equals(oldValue, newValue)
you can be sure thatisNowSelected = !wasSelected
.Of course you also need to return the value:
I also recommend using a
Collection
ofBean
s instead of relying on the string representation of the objects.toString
many not produce unique results andBeans.equals
would be the better choice to compare the objects.