If I create a ListView:
new ListView<>(FXCollections.observableArrayList("1", "2", "3"))
I would expect it to create a ListView with 3 rows. But it doesn't. It creates a ListView of 17 or so rows. Is there a way to tell ListView to always be the height such that whatever items are in it are always shown but no blank rows?
Having it auto width would also be useful, so it's always as wide as the widest row.
One purpose of this is that then it could be used in a ScrollPane. I know it has its own scrollbars, but they don't offer sufficient control.
To limit the height of ListView, wrap the ListView with a Container widget and set the height of the Container to the required height.
I just found out that Paul Marshall's answer can be reducted to a one-liner using Bindings.size that creates a numeric jfx property representing the size of an ObservableList :
listView.prefHeightProperty().bind(Bindings.size(itemListProperty).multiply(LIST_CELL_HEIGHT));
The list cell height must sadly still be hardcoded AFAIK.
Unfortunately there is not a nice, clean size Property of an ObservableList for us to bind to. Instead, it's doable by adding a ListChangeListener on the list, at least, that's how I've done it in the past. By default the size of each row should be 24px, and we need an extra pixel on the top and bottom for the ListView's edges. Otherwise we still have the ListView's scroll bar showing. First we'll create the ObservableList and the ListView, and set the initial height of the ListView:
/* * Each row in a ListView should be 24px tall. Also, we have to add an extra * two px to account for the borders of the ListView. */ final int ROW_HEIGHT = 24; final ObservableList items = FXCollections.observableArrayList("1", "2", "3"); final ListView list = new ListView(items); // This sets the initial height of the ListView: list.setPrefHeight(items().size() * ROW_HEIGHT + 2);
Now we have to add a ListChangeListener to the ObservableList. When the list changes, we simply change the set height of the ListView to match the new number of rows. If we know that we are never going to add or remove items from the ObservableList that is backing the ListView, then we can exclude the listener. Again, the height is the number of rows times the height per row plus two extra pixels for the borders:
/* * This listener will resize the ListView when items are added or removed * from the ObservableList that is backing the ListView: */ items.addListener(new ListChangeListener() { @Override public void onChanger(ListChangeListener.Change change) { list.setPrefHeight(items.size() * ROW_HEIGHT + 2); } });
References: JavaFX ListView Documentation, JavaFX ObservableList Documentation
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With