JTable 中的数据分页

发布于 2024-08-22 01:13:17 字数 225 浏览 4 评论 0原文

我的 Jpanel 中有一个 jbutton。当我单击它时,它会加载我的 Jtable,有时查询会返回如此多的记录(500 行)。所以我想将其限制为 5 条记录。

当查询返回时我想对其进行计数;如果它高于 5,则 Jtable 仅显示前 5 条记录,当用户单击“前进”按钮时,它将显示下 5 条记录。当用户单击“后退”按钮时,将显示前 5 条记录。

我该怎么做? TableModel 有这方面的例子吗?

There is a jbutton in my Jpanel. When I clicked it, it loads up my Jtable, sometimes a query return so many records (500 rows). So I want to restrict it to 5 records.

When query return I want to count it; if it's higher than 5 then Jtable shows up only first 5 record, when user click Forward button it will shows up next 5 record. When user click Back button it will show previous 5 record.

How can I do this? Is there any example for this with TableModel?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

话少情深 2024-08-29 01:13:17

我建议实现一个“分页”TableModel,它提供了整个数据集的窗口以及在整个数据中向前和向后移动的方法。这样,您不需要两个 List 来存储数据,而是需要一个 List 来保存所有数据以及当前位置的标记;例如,

public class ImmutablePagedTableModel extends AbstractTableModel {
  private final List<MyBusinessObject> allData;
  private final int pageSize;
  private int pos;  

  public ImmutablePagedTableModel(List<MyBusinessObject> allData) {
    // Copy construct internal list.  Use ArrayList for random access look-up efficiency.
    this.allData = new ArrayList<MyBusinessObject>(allData);
  }

  /**
   * Returns true if the model has another page of data or false otherwise.
   */
  public boolean hasNextPage() {
    return pos + pageSize < allData.size();
  }

  /**
   * Flips to the next page of data available.
   */
  public void nextPage() {
    if (hasNextPage()) {
      pos += pageSize;

      // All data in the table has effectively "changed", so fire an event
      // causing the JTable to repaint.  
      fireTableDataChanged();
    } else {
      throw new IndexOutOfBoundsException();
    }    
  }

  public int getRowcount() {
    return Math.min(pageSize, allData.size() - pos);
  }

  // TODO: Implement hasPreviousPage(), previousPage();
}

正如 00rush 提到的一种更雄心勃勃的方法是使用 SwingWorker 在后台传输数据。您仍然可以使用分页 TableModel 方法来实现此目的;您只需要确保在追加到 allData 列表末尾时触发适当的 TableModelEvent 即可。

I suggest implementing a "Paged" TableModel which provides a window onto the entire dataset and methods for moving forwards and backwards throughout the data. This way you do not require two Lists to store the data but rather a single List holding all data along with a marker to your current position; e.g.

public class ImmutablePagedTableModel extends AbstractTableModel {
  private final List<MyBusinessObject> allData;
  private final int pageSize;
  private int pos;  

  public ImmutablePagedTableModel(List<MyBusinessObject> allData) {
    // Copy construct internal list.  Use ArrayList for random access look-up efficiency.
    this.allData = new ArrayList<MyBusinessObject>(allData);
  }

  /**
   * Returns true if the model has another page of data or false otherwise.
   */
  public boolean hasNextPage() {
    return pos + pageSize < allData.size();
  }

  /**
   * Flips to the next page of data available.
   */
  public void nextPage() {
    if (hasNextPage()) {
      pos += pageSize;

      // All data in the table has effectively "changed", so fire an event
      // causing the JTable to repaint.  
      fireTableDataChanged();
    } else {
      throw new IndexOutOfBoundsException();
    }    
  }

  public int getRowcount() {
    return Math.min(pageSize, allData.size() - pos);
  }

  // TODO: Implement hasPreviousPage(), previousPage();
}

As 00rush mentions a more ambitious approach would be to use a SwingWorker to stream in the data in the background. You could still use the paged TableModel approach for this; you'd just need to ensure that appropriate TableModelEvents are fired as you append to the end of the allData list.

萤火眠眠 2024-08-29 01:13:17

如果您希望加载大型表,您可能需要使用 SwingWorker(详细信息 此处)线程在后台加载表格。加载 500 行的表应该不成问题。然后,您可以将数据放入合适的对象格式并将其传递给您的 TableModel。

例如,如果您决定使用列表,则在表模型中可以有两个列表:

List allData
List viewData
int startIndex

viewData 列表是 TableModel 接口实现中的 getValueAt(..) 方法所引用的列表。 viewData 列表始终是 allData 的子集(由 startIndex 绑定,长度为 5)。当用户单击“Next”时,您的操作侦听器可以调用 Table 模型上的一个方法,该方法将 startIndex 添加 5(或其他值)。然后,您重新生成 viewData 实例,使其成为 allData 的适当 5 行子集,并调用 fireTableChanged()。如果您扩展了 AbstractTableModel< /a> 首先。

这应该非常容易实现。我认为这比每次想要获取下一组数据时都进行数据库调用要好。恕我直言,最好提前多花一点时间来预加载数据。

If you wish to load a large table, you may want to use a SwingWorker (details here) thread to load the table in the background. Loading a table with 500 rows should not be a problem. You can then put the data into a suitable object format and pass it to your TableModel.

If you decide to use a List for example, in your table model you could have two lists:

List allData
List viewData
int startIndex

The viewData list is what is referenced by the getValueAt(..) method in your implementation of the TableModel interface. The viewData list is always a subset (bound by startIndex, of length 5) of allData. When the user clicks "Next", your action listener could call a method on the Table model that increments startIndex by 5 (or whatever). You then regenerate your viewData instance so that it is the appropriate 5 row subset of allData, and call fireTableChanged(). This will be easy if you have extended AbstractTableModel in the first place.

This should be pretty straightforward to implement. I think its better than making a database call every time you want to get the next set of data. IMHO, its better to take a little bit more time upfront to preload the data.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文