Java 如何为 Swing 中的 JTable 提供分页支持?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1481138/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to provide pagination support to a JTable in Swing?
提问by om.
I have created one GUI in Swing Java in which I have used JTable.Now I want to display next page information into it by using pagination. How should I do that ?
我在 Swing Java 中创建了一个 GUI,其中使用了 JTable。现在我想通过使用分页将下一页信息显示到其中。我该怎么做?
回答by Petros
Paging in a Swing JTablelooks like a nice article.
Swing JTable 中的分页看起来是一篇不错的文章。
Here is an excerpt:
这是摘录:
As far as I remember the solution for this problem lies in the concept of paging: just retrieve the data that the user wants to see and nothing more. This also means you have to sometimes get extra data from the db server (or appserver) if your user scrolls down the list.
Big was my surprise that there wasn't really an out-of-the-box solution (not even a copy- paste solution) for this problem. Anyone that knows one, please don't hesitate to extend my (rather limited) knowledge of the J2EE platform.
So we dug in, and tried to build a solution ourselves. What we eventually came up with was an adapted TableModel class to takes care of the paging.
据我所知,这个问题的解决方案在于分页的概念:只检索用户想要查看的数据,仅此而已。这也意味着如果您的用户向下滚动列表,您有时必须从数据库服务器(或应用程序服务器)获取额外数据。
令我惊讶的是,对于这个问题并没有真正的现成解决方案(甚至没有复制粘贴解决方案)。任何知道的人,请不要犹豫,扩展我对 J2EE 平台的(相当有限的)知识。
所以我们深入挖掘,并试图自己构建一个解决方案。我们最终想出了一个经过调整的 TableModel 类来处理分页。
回答by akf
Another option to implement this is to use a scrollbar-less scrollpane and a couple nav buttons to effect the control. The buttons that have been added are normal JButton
s for the prototype.
实现这一点的另一种选择是使用无滚动条的滚动窗格和几个导航按钮来实现控制。添加的按钮是JButton
原型的普通s。
A quick prototype is added below. It makes a couple assumptions, one of which is that the table model has all of its data. Work could be done to ensure that rows end up flush at the top of the view upon navigation.
下面添加了一个快速原型。它做出了几个假设,其中一个假设是表模型具有所有数据。可以做一些工作来确保行在导航时在视图顶部齐平。
private void buildFrame() {
frame = new JFrame("Demo");
frame.setSize(300, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addStuffToFrame();
frame.setVisible(true);
}
private void addStuffToFrame() {
final JTable table = getTable();
final JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
final JButton next = new JButton("next");
final JButton prev = new JButton("prev");
ActionListener al = new ActionListener(){
public void actionPerformed(ActionEvent e) {
Rectangle rect = scrollPane.getVisibleRect();
JScrollBar bar = scrollPane.getVerticalScrollBar();
int blockIncr = scrollPane.getViewport().getViewRect().height;
if (e.getSource() == next) {
bar.setValue(bar.getValue() + blockIncr);
} else if (e.getSource() == prev) {
bar.setValue(bar.getValue() - blockIncr);
}
scrollPane.scrollRectToVisible(rect);
}
};
next.addActionListener(al);
prev.addActionListener(al);
JPanel panel = new JPanel(new BorderLayout());
JPanel buttonPanel = new JPanel();
buttonPanel.add(prev);
buttonPanel.add(next);
panel.add(buttonPanel, BorderLayout.NORTH);
panel.add(scrollPane, BorderLayout.CENTER);
frame.getContentPane().add(panel);
}
private JTable getTable() {
String[] colNames = new String[]{
"col 0", "col 1", "col 2", "col 3"
};
String[][] data = new String[100][4];
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 4; j++) {
data[i][j] = "r:" + i + " c:" + j;
}
}
return new JTable(data,colNames);
}
回答by martinusadyh
You can try with 2 query, first query is to count total rows in DB and second query is for the realdata :) And for the UI side, you can try like this:
您可以尝试使用 2 个查询,第一个查询是计算 DB 中的总行数,第二个查询是针对真实数据的 :) 而对于 UI 端,您可以这样尝试:
public class MainForm extends javax.swing.JFrame {
private void initDefaultValue() {
rowsPerPage = Integer.valueOf(cmbPageSize.getSelectedItem().toString());
totalRows = Main.getTablePagingService().countComments();
Double dblTotPage = Math.ceil(totalRows.doubleValue()/rowsPerPage.doubleValue());
totalPage = dblTotPage.intValue();
if (pageNumber == 1) {
btnFirst.setEnabled(false);
btnPrevious.setEnabled(false);
} else {
btnFirst.setEnabled(true);
btnPrevious.setEnabled(true);
}
if (pageNumber.equals(totalPage)) {
btnNext.setEnabled(false);
btnLast.setEnabled(false);
} else {
btnNext.setEnabled(true);
btnLast.setEnabled(true);
}
txtPageNumber.setText(String.valueOf(pageNumber));
lblPageOf.setText(" of " + totalPage + " ");
lblTotalRecord.setText("Total Record " + totalRows + " rows.");
List wPComments = Main.getTablePagingService().findAllComment(pageNumber, rowsPerPage);
jTable1.setModel(new CommentTableModel(wPComments));
autoResizeColumn(jTable1);
}
private void btnFirstActionPerformed(ActionEvent evt) {
pageNumber = 1; initDefaultValue();
}
private void btnPreviousActionPerformed(ActionEvent evt) {
if (pageNumber > 1) {
pageNumber -= 1; initDefaultValue();
}
}
private void btnNextActionPerformed(ActionEvent evt) {
if (pageNumber
And in service layer, you just need use limit function like this :
And in service layer, you just need use limit function like this :
public List findAllComment(Integer pageNumber, Integer rowsPerPage) {
try {
List listWP = new ArrayList();
preparedFindAll.setInt(1, (rowsPerPage*(pageNumber-1)));
preparedFindAll.setInt(2, rowsPerPage);
ResultSet rs = preparedFindAll.executeQuery();
while (rs.next()) {
WPComment comment = new WPComment();
comment.setCommentID(rs.getInt("comment_ID"));
comment.setCommentAuthor(rs.getString("comment_author"));
comment.setCommentDate(rs.getDate("comment_date"));
comment.setCommentContent(rs.getString("comment_content"));
listWP.add(comment);
}
return listWP;
} catch (SQLException ex) {
Logger.getLogger(TablePagingServiceJDBC.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
public Integer countComments() {
try {
Integer totalRows = 0;
ResultSet rs = preparedCount.executeQuery();
while (rs.next()) {
totalRows = rs.getInt("count(*)");
}
return totalRows;
} catch (SQLException ex) {
Logger.getLogger(TablePagingServiceJDBC.class.getName()).log(Level.SEVERE, null, ex);
}
return 0;
}
Or you can fork me on github at Project Page Table Paging on Swing:)
或者你可以在 github 上的Project Page Table Paging on Swing上 fork 我:)
回答by andy
I have written a Java pagination tool dataj. It uses JQuery dataTablesplug-in pagination metadata to build up the result page. I have also added some client classes for Java Swing including a TableRowSorter that calls the (server side) sorting instead of sorting inside the table model. Feel free to download it and contact me if you have any questions. It's under Apache 2 license.
我写了一个 Java 分页工具dataj。它使用 JQuery dataTables插件分页元数据来构建结果页面。我还为 Java Swing 添加了一些客户端类,包括调用(服务器端)排序而不是在表模型内部排序的 TableRowSorter。如果您有任何问题,请随时下载并与我联系。它在 Apache 2 许可下。
回答by Stephan
Alternatively, you can make use of the QuickTable
project.
或者,您可以使用该QuickTable
项目。
Screenshot
截屏
Here is the DBTable
component in action:
这是正在运行的DBTable
组件:
The DBTable
component is embedded in a traditionnal JFrame
.
该DBTable
组件嵌入在传统的JFrame
.
Sample code
示例代码
The following sample code produces the window shown in the previous screenshot:
以下示例代码生成上一个屏幕截图中显示的窗口:
import javax.swing.JFrame;
import javax.swing.UIManager;
import quick.dbtable.DBTable;
public class QuickTableFrame extends JFrame {
private static final long serialVersionUID = -631092023960707898L;
public QuickTableFrame() {
try {
// Use system look and feel
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
// set Frame properties
setSize(300, 200);
setVisible(true);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
// create a new quicktable
DBTable dBTable1 = new DBTable();
// add to frame
getContentPane().add(dBTable1);
// set the database driver to be used, we are using jdbc-odbc driver
dBTable1.setDatabaseDriver("org.h2.Driver");
/*
* set the jdbc url,"quicktabledemo" is the data source we have
* created for the database
*/
dBTable1.setJdbcUrl("jdbc:h2:mem:test;INIT=create table employee as select * from CSVREAD('test.csv');");
// set the select statement which should be used by the table
dBTable1.setSelectSql("select * from employee");
// to create the navigation bars for the table
dBTable1.createControlPanel();
// connect to database & create a connection
dBTable1.connectDatabase();
// fetch the data from database to fill the table
dBTable1.refresh();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// create a new table frame
QuickTableFrame myframe = new QuickTableFrame();
}
}
Resources and dependencies
资源和依赖
test.csv
测试文件
empid,emp_name,emp_dept,emp_salary
1,Azalia,ornare,114918
2,Jade,tristique,152878
3,Willa,In scelerisque scelerisque,166733
...
H2
H2
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.187</version>
</dependency>