JavaFX: TableView with Pagination and Custom Sorting

This blog shows how to add Pagination and custom Sorting to the JavaFX TableView element.
If you are already aware of the challenges/issues with TableView element, jump to the Implementation section, otherwise continue reading. Source code is available for download from git hub here. or get it from here:
https://github.com/incepttechnologies/JavaFXTableWithPagination.git

Background

The TableView control of JavaFX is a good component to display data in rows and column format. It also has sorting built into it. By default, sorting is enabled on a column; and the column can be sorted in following modes -ascending, descending or null order.

TableView, unlike its HTML counterpart, can be used only for data display and cannot be used for layout. For layout, one can use GridPane.

Quite often, Pagination feature is desired to display large quantity of data. JavaFX TableView control lacks built-in features like pagination and custom sorting.

To add pagination feature to tableview, JavaFX's Pagination control can be used. However one has to manage "what to display on the page" in the Pagination control action.

Adding Pagination, however, breaks the built-in "Sorting" feature of TableView. The TableView sort works only on the list that is currently displayed and NOT on the entire list.
For example: If there are in total 20 records to be shown with 10 records per page i.e. 2 pages, then a sort on first page will sort items that are visible only on the first page and not take into account items on second page; likewise a sort on second page will sort items only on that page.

About the Example in this blog

This example adds pagination feature to TableView Control and also adds custom sorting to "Id" column; the default sorting on "Name" column is kept on and and sorting on "Age" column is disabled. It also shows how to dynamically add a row to the TableView.

Implementation

In brief, Pagination on TableView is implemented by attaching a change listener to  currentPageIndex Property of Pagination control. Whenever, the index changes, a sub-list corresponding to the page index is displayed.
Sorting is implemented by first turning OFF the default sort feature of tableView column and then adding a event handler for button [added to column header - onclick]  to trigger sorting.

Layout and General explanation of Code

The layout of the page (TableView.fxml) is very simple, it has a TableView at the top, bunch of labels and TextFields for adding a new row and then the pagination component.

TableViewController.java manages all the TableView processing. The list of Objects to be displayed in TableView is initialized at the declaration stage. The methods of particular importance in this class are initialize(...), sort(), updatePersonView() and  initializeTable(). The last one has the setup for TableView, let's look at that:

here I am adding an image to a Button control "Id" and then setting that button as Graphic into the tableColumn. (Note; this can only be done programmatically because if you try to add a button to a column in fxml, it throws error). This button will work as column header and clicking it would activate sort (toggling between ascending and descending order). The default sorting feature (which is on by default) of the column is turned off, so that it doesn't mess up with my cuom sort.
The rest of the code in this method creates the other two column ("Name" and "Age").
Now onto the initialize(..) method


first a listener is added for to the PaginationControl, whenever the index changes(that would be when user clicks on page links), this listener is activated, and a new list of objects "Person" is displayed by calling updatePersonView()
An EventHandler is added to Save() button, whenever save button is clicked data is read from the input fields and added in as new record.
Finally a EventHandler is added to the "Id" button, which sort of is header for first column "ID". A click on this button/header activates sort. The sort method is implemented using custom comparator.

In UpdatePersonView(), a sublist of "Person" objects is created based on the current page index.

Source

Source code is available for download from hit hub here. or get it from here:
https://github.com/incepttechnologies/JavaFXTableWithPagination.git

6 comments: