When you hop into the Main.fxml file you'll see that I've created an ListView in FXML and gave it the fx:id listview. I add all the Students to an ObservableList, so when changes in that list occur, they get updated to the ListView.

My controller class implements Initalizable, the method initialize is called after its root element has been completely loaded.

Set the ListCell to our ListView

Now, in my initalize method you see that I set the LisViews cell factory. In this example I do this with an lambda expression, but of course you can do it the old way.

Well now I explain what happens here.
First, the updateItem method is called for every visible item in our listview. So you don't want much code in here, because if you scroll fast in your listview it could produce some lags.

So we only want something to happen if we have an student and if our cell is not empty.

First we check if we don't have an FXMLLoader. If we don't have one we load our custom cell, and set this class to our controller class for the cell.

After the cell has been loaded, we can do some simple logic in our ListCell. In my example I set the first label to the student id, the second label to the student name, and then I set the icon in my cell to the students gender.