Java Swing之JTable分页显示数据

        使用表格显示数据时经常用到分页显示技术。在如下情况中经常用到。

        一是数据量较大。表格中的数据行数非常多,一次性全部展示会导致页面加载缓慢,用户滚动查找信息困难。

        二是数据加载时间长。如果从数据源获取数据并渲染到表格中的过程耗时较长,分页可以减少用户的等待时间,让用户更快地看到部分数据。

        三是屏幕空间有限。当屏幕尺寸有限时,无法一次性展示大量数据,分页可以更好地适应屏幕,提供更清晰和易于操作的界面。

        四是数据更新不频繁。如果数据的更新频率较低,分页可以避免用户每次都需要加载大量可能不变的数据。

        五是需要精确控制数据展示。当希望用户按照特定的顺序和批次浏览数据,或者根据特定的条件限制每页显示的数据量时,分页是一个有效的方式。

        六是降低服务器和网络压力。对于服务器资源有限或网络带宽较低的情况,分页可以减少每次请求的数据量,减轻服务器和网络的负担。特别是在高并发访问的情况下,分页能确保系统的稳定运行。

        七是提高数据安全性。对于某些敏感数据,分页可以限制用户在一次操作中能够访问的数据量,降低数据泄露的风险。

        以上是分页显示数据常用情景,也是分页显示数据的优点。在Java Swing组件中JTable作为表格组件,可以根据实际需求采取分页显示的方式,满足用户和系统的需求。以下从个人应用角度探讨分页显示逻辑的设计与实现。

        本文基于已经连接数据库、创建了表格并可以显示内容基础上,按照如图1红色框中部分设计分页显示功能组件的构成及代码实现。

6290d5f5741447ee894e812bd212b9bd.png

图1 分页显示页面

 

        1.用标签显示记录总数、页面总数及当前页信息

        本部分设计的技术逻辑是:使用从数据表中得到的查询记录集总行数/页面大小(每页显示的行数)得到总页数,设置第一页为当前页,将页面大小、总行数、当前页、总页数按照一定格式显示在标签上。标签内有关数据会随着相关操作而动态改变。当单击页面切换按钮(首页、上页、下页、尾页)时,动态改变当前页页码。当改变查询条件时记录总数、页面总数随之改变。

假设使用rows表示查询记录集总行数,pagesize表示页面大小(页面显示行数,本文用5表示页面大小),pages表示总页数,currentpage表示当前页(起始默认为第1页),使用的主要技术如下。

        (1)获取总行数

        使用count函数构造查询语句,直接获取符合条件的记录总数。

String sql = "select  count(*)  from  tableName  where  selectCondition"

        以上语句中 tableName、selectCondition分别表示查询表名和查询条件,根据实际更换为读者的表即可。

        假设获取到的记录集为rs,以下代码可以获取查询记录集总行数。

whie(rs.next())
    rows = rs.getInt(1);//查询结果中只有一个count值

        (2)计算总页数

        用总行数除以页面大小的结果作为ceil函数的参数,基于确定的页面大小计算要显示的总页数pages。

pages = (int)Math.ceil(double(rows/pagesize));

          (3)设置标签文本显示相关信息

String lbltext = "共有 "+rows+" 条记录,每页 "+pagesize+" 条,第 "+currentpage+"/"+pages+" 页");

         将lbltext设置为标签的文本即可。

         2.用按钮实现首页、上页、下页、尾页的功能

        使用JButton组件定义四个按钮,设置合理的尺寸和位置,其文本分别为首页、上页、下页、尾页。当分别点击四个按钮时,表格显示指定页的记录内容,从而实现查询结果分页显示之目的。

        若想正确显示指定页的内容,就必须准确找到与指定页对应的那些记录,如何确定页面和记录之间的对应关系是分页显示的核心问题。以下从两种情况探讨确定页面与记录之间的对应关系。

        (1)查询记录总数比较少

        当查询记录比较少时,在系统性能和资源消耗允许下,可以考虑用使用带索引的数组、集合来存储记录内容,通过明确规范索引和页面、页面大小之间的对应关系快速找到数据,进而存储到表格中。以下代码是使用ArrayList集合存储查询记录集的例子。

        

ArrayList<String[]> rowdatas = new ArrayList<>();
while(rs.next()) {//假设已经获得记录集rs
//获得每条记录的各个字段值,分别用userid、userpwd、usertype表示。
	String userid = rs.getString(0);
	String username = rs.getString(1);
	String userpwd = rs.getString(2);
	String usertype = rs.getString(3);
	String[] rowdata = {userid ,username,userpwd,usertype};			 
    rowdatas.add(rowdata);//将记录添加到集合中,便于分页使用。	
}

        

        截止现在,我们已经将查询到的所有记录存储到了ArrayList列表中,该列表是一个有序集合,可以使用索引值访问其中的元素。

        假若当前要显示第n页的数据,每页显示的记录是pagesize,根据索引与元素之间的对应关系,则第n页数据的开始元素索引是(n-1)*pagesize,对应列表中的rowdatas[(n-1)*pagesize]元素,最后一个元素索引是n*pagesize-1,对应列表中rowdatas[n*pagesize-1]元素。基于此,使用如下循环可以将第n页数据添加到JTable中,如以下代码所示。

tablemodel.setRowCount(0);
int start = (n-1)*pagesize;
int end = n*pagesize;
if(end>rows)
	end=rows;
for(int i=start;i<end;i++)
	tablemodel.addRow(rowdatas.get(i));	

        

        (2)查询记录总数非常大

         如果查询获得的记录集非常大,使用集合会导致内存资源消耗多、系统性能降低等问题,此时不宜采用集合存储查询结果。

         对于大型数据表记录的分页显示,通常使用select语句结合limit函数可以更有效。在limit函数中,传递符合需求的查询起始点和查询记录条数参数,起到仅查询获取指定范围内数据的作用。将这些数据都填充到JTable中,也就实现分页显示的目的。

        以上方法实现的主要代码参考如下。

tablemodel.setRowCount(0);//清空表格原有的数据
sql = "select * from tablename limit"+(currentpage-1)*pagesize+","+pagesize;
conn = new ConnectDB();//创建数据库连接对象,使用封装类ConnectDB()		
rs = conn.stmt.executeQuery(sql);//执行查询语句获取记录集
while(rs.next()){
	String stuid = rs.getString(0);
	String stuname = rs.getString(1);
	String stutel = rs.getString(2);
	String stuschool = rs.getString(3);
    String stupro = rs.getString(4);
    String[] rowdata ={stuid,stuname,stutel,stuschool,stupro};
	tablemodel.addRow(rowdata);//将记录添加到表格模型中
}		

        以上代码sql语句中的limit函数包含两个参数,第一个表示起始位置,第二个表示查询记录数,其中currentpage表示指定显示的页码,如果是第n页,使用currentpage=n完成页面指定。

        3.用按钮实现页面跳转

        在JTable显示某一页内容之后,若需要显示首页、尾页、前页、后页,在当前currentpage值的基础上改变其值,根据改变后的页面值查询得到指定范围内的记录,然后填充到表格中,从而能实现分页显示功能。按钮与currentpage的改变关系如下。

        【首页】对应currentpage = 1;

        【尾页】对应currentpage = pages;//pages是页面总数

        【前页】对应currentpage -= 1;

        【后页】对应currentpage += 1;

        下面以点击【首页】按钮为例实现分页显示。

if(currentpage!=1) //将当前页设为第1页,显示首页数据
	 currentpage=1;
tablemodel.setRowCount(0);
sql="select * from studentinfo limit "+(currentpage-1)*pagesize+","+pagesize;
conn = new ConnectDB();//创建数据库连接对象		
rs = conn.stmt.executeQuery(sql);
while(rs.next()){
	String stuid = rs.getString(0);
	String stuname = rs.getString(1);
	String stutel = rs.getString(2);
	String stuschool = rs.getString(3);
    String stupro = rs.getString(4);
    String[] rowdata ={stuid,stuname,stutel,stuschool,stupro};
	tablemodel.addRow(rowdata);//将记录添加到表格模型中
}	

        4.用跳转按钮跳转到指定页

        当显示页数比较多,可以使用JComboBox列表显示所有的页码,从列表选择某一页码作为currentpage,依此查询指定范围内的记录,可以快速定位并显示数据。具体实现不再赘述。

        以上是本文的主要内容。表格分页显示的根本是获取显示总数,根据页面大小确定总页数,根据指定页确定显示数据集或范围,进而将数据填充到表格中,实现分页显示功能。作者应用不够熟练,探究较少,仅作抛砖引玉,供读者熟悉基本的算法和实现路径,为后续提升和强化应用奠定基础。

 

  • 31
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
JTable 是一个非常常见的 Java Swing 控件,它可以方便地展示数据。如果数据量比较大,我们往往需要进行分页查看。下面是 JTable 分页查询的完整实现: 首先,我们需要定义一个分页类 PagingModel,用来管理分页相关的信息,如当前页码、每页显示的行数、总记录数等等。代码如下: ```java public class PagingModel { private int currentPage; // 当前页码 private int pageSize; // 每页显示的行数 private int totalRecords; // 总记录数 private int totalPages; // 总页数 public PagingModel(int pageSize, int totalRecords) { this.currentPage = 1; this.pageSize = pageSize; this.totalRecords = totalRecords; this.totalPages = (totalRecords + pageSize - 1) / pageSize; } public int getCurrentPage() { return currentPage; } public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public int getTotalRecords() { return totalRecords; } public void setTotalRecords(int totalRecords) { this.totalRecords = totalRecords; this.totalPages = (totalRecords + pageSize - 1) / pageSize; } public int getTotalPages() { return totalPages; } public void setTotalPages(int totalPages) { this.totalPages = totalPages; } public int getFirstResult() { return (currentPage - 1) * pageSize; } public int getMaxResults() { return pageSize; } public boolean isFirstPage() { return currentPage == 1; } public boolean isLastPage() { return currentPage == totalPages; } public void nextPage() { if (!isLastPage()) { currentPage++; } } public void previousPage() { if (!isFirstPage()) { currentPage--; } } } ``` 接下来,我们需要定义一个数据模型类,用来管理 JTable数据。代码如下: ```java public class MyTableModel extends AbstractTableModel { private List<Object[]> data; private String[] columnNames; public MyTableModel(List<Object[]> data, String[] columnNames) { this.data = data; this.columnNames = columnNames; } @Override public int getRowCount() { return data.size(); } @Override public int getColumnCount() { return columnNames.length; } @Override public String getColumnName(int columnIndex) { return columnNames[columnIndex]; } @Override public Object getValueAt(int rowIndex, int columnIndex) { return data.get(rowIndex)[columnIndex]; } public void setData(List<Object[]> data) { this.data = data; fireTableDataChanged(); } } ``` 其中,data 是一个 List,用来存储 JTable数据。每个元素都是一个 Object[],代表一行数据。columnNames 是一个 String[],用来存储 JTable 的列名。 接下来,我们需要定义一个分页查询的方法,用来查询数据并更新 JTable。代码如下: ```java public void queryDataByPage(int pageNum) { PagingModel pagingModel = new PagingModel(pageSize, totalRecords); pagingModel.setCurrentPage(pageNum); List<Object[]> data = // 执行查询语句,获取数据 myTableModel.setData(data); jTable.setModel(myTableModel); updatePageStatus(pagingModel); } private void updatePageStatus(PagingModel pagingModel) { currentPageLabel.setText(pagingModel.getCurrentPage() + ""); totalPagesLabel.setText(pagingModel.getTotalPages() + ""); totalRecordsLabel.setText(pagingModel.getTotalRecords() + ""); previousButton.setEnabled(!pagingModel.isFirstPage()); nextButton.setEnabled(!pagingModel.isLastPage()); } ``` 其中,pageSize 表示每页显示的行数,totalRecords 表示总记录数。我们先根据当前页码和总记录数计算出总页数,然后执行查询语句,获取数据。最后,更新 JTable数据模型和分页相关的信息。 最后,我们需要在界面上添加一些组件,如 JTable分页按钮、分页信息等等。代码如下: ```java JTable jTable = new JTable(); MyTableModel myTableModel = new MyTableModel(new ArrayList<>(), new String[]{/* 列名 */}); int pageSize = 10; int totalRecords = // 执行查询语句,获取总记录数 PagingModel pagingModel = new PagingModel(pageSize, totalRecords); JButton previousButton = new JButton("上一页"); JButton nextButton = new JButton("下一页"); JLabel currentPageLabel = new JLabel(pagingModel.getCurrentPage() + ""); JLabel totalPagesLabel = new JLabel(pagingModel.getTotalPages() + ""); JLabel totalRecordsLabel = new JLabel(pagingModel.getTotalRecords() + ""); previousButton.addActionListener(e -> { pagingModel.previousPage(); queryDataByPage(pagingModel.getCurrentPage()); }); nextButton.addActionListener(e -> { pagingModel.nextPage(); queryDataByPage(pagingModel.getCurrentPage()); }); JPanel pagePanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); pagePanel.add(previousButton); pagePanel.add(currentPageLabel); pagePanel.add(new JLabel("/")); pagePanel.add(totalPagesLabel); pagePanel.add(nextButton); JPanel infoPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); infoPanel.add(new JLabel("共 " + totalRecordsLabel + " 条记录")); JFrame frame = new JFrame(); frame.add(new JScrollPane(jTable), BorderLayout.CENTER); frame.add(pagePanel, BorderLayout.SOUTH); frame.add(infoPanel, BorderLayout.NORTH); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); ``` 其中,上一页和下一页按钮的 ActionListener 中分别调用 queryDataByPage 方法来更新 JTable分页信息。界面上方显示分页信息,下方显示 JTable分页按钮。 以上就是 JTable 分页查询的完整实现。需要注意的是,这里只是一个简单的示例,实际应用中可能需要处理更多的异常情况和分页相关的细节。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值