Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you get JavaFX ListView to be the height of its items?

Tags:

javafx-2

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.

like image 261
mentics Avatar asked Jul 02 '13 15:07

mentics


People also ask

How to set size of ListView?

To limit the height of ListView, wrap the ListView with a Container widget and set the height of the Container to the required height.


2 Answers

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.

like image 190
Alexandre Mazari Avatar answered Nov 10 '22 21:11

Alexandre Mazari


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

like image 21
Paul Marshall Avatar answered Nov 10 '22 20:11

Paul Marshall