I know two VirtualFlow
implementations—one native to JavaFX
and another from the Flowless library. I know how to use Flowless VirtuaFlow
, but now, I would like to try using the JavaFX VirtualFlow
. However, I don't understand how to pass an ObservableList<T>
items to this VirtualFlow
. Here is my code:
public class NewMain extends Application {
public class VirtualCell<T> extends IndexedCell<T> {
}
private final VirtualFlow<VirtualCell<String>> virtualFlow = new VirtualFlow<>();
@Override
public void start(Stage primaryStage) {
this.virtualFlow.setCellFactory(v -> new VirtualCell<>());
List<String> list = new ArrayList<>();
for (var i = 0; i < 100; i++) {
list.add("Item " + i);
}
ObservableList<String> items = FXCollections.observableArrayList(list);
//this.virtualFlow.set items ????
var root = new VBox(this.virtualFlow);
Scene scene = new Scene(root, 600, 200);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Could anyone say how to do it?
VirtualFlow
doesn't directly accept ObservableList
.
You should extend ListCell<>
to handle string directly.
public class VirtualCell extends IndexedCell<String> {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
} else {
setText(item);
}
}
// it gave me a missing skin error, this fixed it.
@Override
protected Skin<?> createDefaultSkin() {
return new CellSkinBase<>(this);
}
}
the VirtCell
class extends IndexedCell
and overrides the updateItem
method to properly display the item.
Then you need to set cell factory:
@Override
public void start(Stage primaryStage) {
List<String> list = new ArrayList<>();
for (var i = 0; i < 100; i++) {
list.add("Item " + i);
}
ObservableList<String> items = FXCollections.observableArrayList(list);
virtualFlow.setCellFactory(vf -> new VirtualCell());
virtualFlow.setCellCount(items.size());
virtualFlow.setCellFactory(vf -> new VirtualCell() {
@Override
public void updateIndex(int index) {
super.updateIndex(index);
if (index >= 0 && index < items.size()) {
updateItem(items.get(index), false);
} else {
updateItem(null, true);
}
}
});
var root = new VBox(this.virtualFlow);
Scene scene = new Scene(root, 600, 200);
primaryStage.setScene(scene);
primaryStage.show();
}