ListView<Thing> listView = new ListView<>();
However this only displays the result of calling Thing.toString()
on the objects. To show more
complex information you need to customise the ListCell
. Start by providing a factory which creates new, customised cells.listView.setCellFactory(new Callback<ListView<Thing>, ListCell<Thing>>() {
@Override
public ListCell<Thing> call(ListView<Thing> p) {
return new ThingCell();
}
});
JavaFX maintains some kind of relationship between ListCell
s and items in the list; it seems to
be roughly one cell per visible row, not one cell per item in the list.
You need to override updateItem()
in Cell
to attach a list item to a cell.public class ThingCell extends ListCell<Thing> {
@Override
protected void updateItem(Thing t, boolean isblank) {
super.updateItem(t, isblank);
...
}
}
In other words, JavaFX uses the factory to create some cells, then attaches the list's contents to them.
As the list is scrolled, different objects will be attached in turn.
Bear in mind, t
may be null - either because you've added a null object to the list,
or because JavaFX wants a cell to suitable for displaying an empty row.
In the latter case, isblank
will be true.
The appearance of the cell may be the same for either, in which case you can ignore isblank
.When an object is attached, remember to bind its properties to the cell, instead of just setting them. If the item then changes 'internally', the list will update automatically. For example, suppose
Thing
has a title property. If you do this:protected void updateItem(Thing t, boolean isblank) {
super.updateItem(t, isblank);
if (t != null) {
setText(t.titleProperty().get());
}
else {
setText("");
}
}
the item will display correctly when it is added to the list (and also if JavaFX re-attaches the objects),
but if someone calls thing.titleProperty().set("New text")
the list will not change.
Instead, tryprotected void updateItem(Thing t, boolean isblank) {
super.updateItem(t, isblank);
if (t != null) {
textProperty().bind(t.titleProperty());
}
else {
textProperty().unbind();
textProperty().set("");
}
}
Of course, if the list items never change after they've been added to the list, it isn't necessary to create the bindings and the first method can be used.
thank you
ReplyDelete