【问题标题】:JTable + TableModel cache fetch event for lazy instantiation?用于延迟实例化的 JTable + TableModel 缓存获取事件?
【发布时间】:2009-09-04 17:53:51
【问题描述】:

场景:

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

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

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

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

编辑: 澄清一下,这里的重点是能够一次获取一组可见表行的内容,而不是必须自己获取每一行的内容.

【问题讨论】:

  • 为了保持模型视图为 1-n 关系,我认为最好不要查询视口,而只依赖模型上执行的实际请求。自己检查视口不会更快。为未填充的单元格返回“null”是没有问题的,因为当您的实际大量数据来自后端时,您可以只生成 tableRow 事件。 jtable 将再次刷新。您可以在每个 model.getValue() 请求时重置一个计时器。并且一旦定时器触发(比如 10 毫秒),检索在一个批量请求中查询的记录。

标签: swing caching jtable tablemodel


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多