JavaFX添加分页表格


第一步:创建带有分页功能的TableView

1. 首先我们新建一个Page类,用来管理数据

  • Page.java: 省略getter和setter方法
import javafx.beans.property.SimpleIntegerProperty; import java.util.List; public class Page<T> { private SimpleIntegerProperty totalRecord; // total record number in source data private SimpleIntegerProperty pageSize; // the number of data in per page private SimpleIntegerProperty totalPage; // total page number private List<T> rowDataList; // total data /** setter ** /** getter **/ /** * @param rowDataList * @param pageSize the number of data in per page */ public Page(List<T> rowDataList, int pageSize) { this.totalRecord = new SimpleIntegerProperty(); this.totalPage = new SimpleIntegerProperty(); this.rowDataList = rowDataList; this.pageSize = new SimpleIntegerProperty(pageSize); initialize(); } private void initialize() { totalRecord.set(rowDataList.size()); // calculate the number of total pages totalPage.set( totalRecord.get() % pageSize.get() == 0 ? totalRecord.get() / pageSize.get() : totalRecord.get() / pageSize.get() + 1); // add listener: the number of total pages need to be change if the page size changed pageSize.addListener((observable, oldVal, newVal) -> totalPage.set( totalRecord.get() % pageSize.get() == 0 ? totalRecord.get() / pageSize.get() : totalRecord.get() / pageSize.get() + 1) ); } /** * current page number(0-based system) * * @param currentPage current page number * @return */ public List<T> getCurrentPageDataList(int currentPage) { int fromIndex = pageSize.get() * currentPage; int tmp = pageSize.get() * currentPage + pageSize.get() - 1; int endIndex = tmp >= totalRecord.get() ? totalRecord.get() - 1 : tmp; // subList(fromIndex, toIndex) -> [fromIndex, toIndex) return rowDataList.subList(fromIndex, endIndex + 1); } } 
  • 这个Page类的作用是传入一个需要分页的数据(rowDataList)和每页显示的行数(pageSize),然后在initialize()方法中自动计算:数据的总记录数(totalRecord),总页数(totalPage)。
  • 这里使用了SimpleIntegerProperty类,这个类使得我们方便地为变量添加监听器。
        pageSize.addListener((observable, oldVal, newVal) -> totalPage.set( totalRecord.get() % pageSize.get() == 0 ? totalRecord.get() / pageSize.get() : totalRecord.get() / pageSize.get() + 1) ); 

在程序中,为变量pageSize添加了一个监听器,如果pageSize的值改变,那么总页数(totalPage)也需要随之改变。

  • Page.getCurrentPageDataList(int currentPage)会根据传入的页码,返回当前页的数据
  • 使用泛型,便于组件的重用

2. 添加分页功能到TableView

  • TableWithPaginationAndSorting.java: 省略getter方法
import javafx.collections.FXCollections; import javafx.scene.control.Pagination; import javafx.scene.control.TableView; public class TableWithPaginationAndSorting<T> { private Page<T> page; private TableView<T> tableView; private Pagination tableViewWithPaginationPane; /** getter **/ public TableWithPaginationAndSorting(Page<T> page, TableView<T> tableView) { this.page = page; this.tableView = tableView; tableViewWithPaginationPane = new Pagination(); tableViewWithPaginationPane.pageCountProperty().bindBidirectional(page.totalPageProperty()); updatePagination(); } private void updatePagination() { tableViewWithPaginationPane.setPageFactory(pageIndex -> { tableView.setItems(FXCollections.observableList(page.getCurrentPageDataList(pageIndex))); return tableView; }); } } 
  • 这个类中最重要的是方法updatePagination,这个方法体中设置了Pagination的页面工厂,这里使用Lambda表达式传入一个回调方法,回调方法会在一个页面被选中时触发。它会加载并返回被选中页面的内容。如果当前被选中的页面索引不存在,则必须返回null值。在这个回调方法中:我们接收传过来的当前页码(pageIndex,从0开始),然后利用Page对象的getCurrentPageDataList(pageIndex)方法获取当页的数据,转换格式并添加到TableView中,最后返回TableView。

关于page factory,可以将它想象成一个加工厂,它负责根据提供的页码生产对应的页面,所以,你可以根据不同的页码显示不同的内容。并且这里我们不用每次都新建一个表格,只需要每次将数据添加到建好了的表格框架

 
 
image.png
  • tableViewWithPaginationPane.pageCountProperty().bindBidirectional(page.totalPageProperty());这一段代码是将PaginationpageCountPropertyPage对象的page.totalPageProperty属性进行双向绑定,这样他们的值就会同步:其中一个改变,另一个也会改变,并且值保持一样。
    如果不使用Lambda,也可以使用匿名函数:
    private void updatePagination() { tableViewWithPaginationPane.setPageFactory(new Callback<Integer, Node>() { @Override public Node call(Integer pageIndex) { tableView.setItems(FXCollections.observableList(page.getCurrentPageDataList(pageIndex))); return tableView; } }); } 

3. 建立一个测试类

我们先建立一个测试类来测试我们已经开发的功能。

import javafx.application.Application; import javafx.collections.FXCollections; import javafx.scene.Scene; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.layout.BorderPane; import javafx.stage.Stage; import java.util.Arrays; import java.util.List; public class TableWithPaginationAndSortingTest extends Application { @Override public void start(Stage primaryStage) throws Exception { // create table TableView<People> peopleTable = createTable(); // get data List<People> peopleList = getTableData(); peopleTable.setItems(FXCollections.observableList(peopleList)); // create Page object Page<People> page = new Page<>(peopleList, 2); // add pagination into table TableWithPaginationAndSorting<People> table = new TableWithPaginationAndSorting<>(page, peopleTable); Scene scene = new Scene(new BorderPane(table.getTableViewWithPaginationPane()), 300, 300); primaryStage.setScene(scene); primaryStage.show(); } private TableView<People> createTable() { TableView<People> table = new TableView<>(); TableColumn<People, String> nameCol = new TableColumn<>("name"); nameCol.setCellValueFactory(new PropertyValueFactory("name")); TableColumn<People, Integer> ageCol = new TableColumn<>("age"); ageCol.setCellValueFactory(new PropertyValueFactory("age")); table.getColumns().addAll(nameCol, ageCol); table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); return table; } private List<People> getTableData() { return Arrays.asList(new People[]{ new People("Huang1", 18), new People("Huang2", 11), new People("Huang3", 13), new People("Huang4", 28), new People("Huang5", 38) } ); } public class People { private String name; private int age; public People(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } } 
  • 我们创建了一个内部类People用作表格展示,然后使用方法createTable()getTableData()来创建TableView和产生表格数据。
  • start()方法中将所有组件组装起来。
     

     

     

  • 我们带有分页功能的TableView创建成功了,我们可以点击表头进行排序,但是这是局部排序,只能对当前页的内容进行排序。


     
     

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM