2

设想:

您正在使用带有自定义 TableModel 的 JTable 来查看位于数据库或网络或其他任何地方的某个集合的内容。

完成这项工作的蛮力方法是一次加载整个集合。假设由于需要资源,这不切实际。

解决该问题的简单方法是按需获取行,一次一行,因为 JTable 呈现每一行,并调用 TableModel.getValueAt(); 根据需要缓存。但是,这会导致对数据库的大量点击。

有没有办法监听 JTable 的滚动/视口事件,以确定在呈现每个单元格之前要显示哪些行?如果是这样,我想拦截并导致我的自定义 TableModel 一次预取一页。

编辑:只是为了澄清,这里的重点是能够在一批中获取一组可见表行的内容,而不必自己获取每一行的内容。

4

2 回答 2

3

看看http://www.javaworld.com/javaworld/javatips/jw-javatip137.html文章。在本文中,有一个自定义 TableModel 能够从数据库中检索“块”行

该场景的另一种解决方案虽然不完全是您正在寻找的,但将延迟加载每一行而不是预取。请参阅我自己的帖子(在谷歌搜索“JTable 绑定到延迟加载的数据库”)以了解如何执行此操作。这个想法是,当向 tablemodel 询问未缓存/加载的行时,它将为每列返回“wait..retrieving”字符串(假设所有列都是字符串)。同时它将在另一个线程中安排一个任务(使用 ExecutorService)。然后任务将从数据库中检索数据并更新数据模型。在我的帖子中,我实际上使用了 Beans 绑定,所以使用自定义列表而不是自定义表格模型。但我相信你可以推断出这个想法。

于 2010-01-14T11:26:15.690 回答
2

实际上,这正是 JTable 所允许的。如果 getRowCount() 方法准确地反映了有多少记录,那么当绘制单元格时,只查询可见部分。我认为通过监听视口进行预取不会更快。

您可以等待所有 getvalue 请求。记录那些,返回“null”或已经缓存的值。然后在没有调用 getvalue 后说 20 ms 对所有记录的单元格进行实际请求。并在模型上触发 rowUpdated 事件,以便 JTable 再次重绘。

**[编辑]**您可以维护在模型上查询的最后记录的列表。您的列表不需要长于屏幕上可见的行数。在几毫秒内没有查询 getValue() 后,您可以向后端执行此异步批量请求

这里唯一的问题是排序/过滤算法。当您查询视口并让数据依赖于它时,您的数据和视图之间存在 1-1 关系。JTable 本身没有的东西。但我想没有办法解决这个问题。我将启用 IDE 调试器来挖掘 sun 代码。然后看看他们的渲染实现如何找出要重绘的行。我不知道。

于 2009-09-15T07:16:11.960 回答