当 SQL 进行排序时,如何启用 GUI 行为来对 JTable 进行排序?

发布于 2024-07-21 08:08:50 字数 1153 浏览 5 评论 0原文

如何启用 JTable 图标和行为以按列对表行进行排序,而不让它使用比较谓词进行排序? 也就是说,如何告诉表头在正在使用的列中显示升序/降序排序顺序的箭头,并让它在排序顺序/列更改时调用适当的方法?

我正在尝试创建一个由 SQL 查询或视图支持的(可编辑、可过滤、可排序)JTable。 这些行可能不适合内存,并且可能无法干净地映射到 java 对象,因此我想在 SQL 中进行所有排序/过滤。 我已经编写了用于更改查询以适应按列排序、按值过滤和可见列的代码。

为了使用它,我计划使用 TYPE_SCROLL_SENSITIVE,CONCUR_UPDATABLE 编写一个基于 ResultSet 的 JTableModel,这样对数据库的更改就会传播到 ResultSet。 我将定期(每秒几次)强制刷新 ResultSet 中的可见 JTable,以便用户可以看到对数据库的更改。 用户对表的更改将在验证后传递到可更新的结果集。

我已经了解了如何正常进行排序,但大多数实现似乎依赖于 JTable 创建带有 Comparator 谓词的 javax.swing.RowSorter,或者依赖于维护在更改时触发事件的已排序行列表。 所以,我的问题是:

ORM 框架不能回答这个问题,因为数据不能很好地映射到实体对象。 另外,我使用的 DBMS 是 H2。

编辑:不幸的是,基于应用比较器或对行对象进行排序谓词的可排序 JTable 库也不合适。 我不相信我能够将所有对象保存在内存中以便执行排序。 此问题使我无法使用 SwingX JXTables、GlazedLists 或类似的库。 我希望我可以,但我不能。 期间。

** 我将处理数千行,可能数百万行,以及许多列。 是的,我确实需要使用 SQL 来进行排序和过滤。**

问题:(按重要性降序排列)

  1. 如何显示用于对行进行排序的列的指示器?
  2. 当左键单击列标题以更改排序顺序时,如何让 JTable 触发适当的事件?
  3. 有没有更简单的方法来强制 JTable 在数据库更改时更新?
  4. 是否有一个库可以使这一切变得更加容易(连接数据库查询或视图和 JTables)?
  5. 当我这样设计系统时,我会遇到可怕的问题吗?

How do I enable JTable icons and behaviors for sorting table rows by a column, without letting it use a comparison predicate to do the sorting? That is to say, how do I tell the table headers to show the arrow for ascending/descending sort order in the column being used, and get it to call appropriate methods when sort order/column change?

I am trying to create an (editable, filterable, sortable) JTable backed by an SQL query or view. The rows may not fit in memory, and may not map cleanly to java objects, so I want to do all sorting/filtering within SQL. I have already written the code for changing a query to accommodate sorting by column, filtering by values, and visible columns.

To use this, I am planning to write a JTableModel based on a ResultSet with TYPE_SCROLL_SENSITIVE, and CONCUR_UPDATABLE, so changes to the DB get propagated to the ResultSet. I will periodically (several times a second) force a refresh of the visible JTable from the ResultSet, so changes to the database become visible to the user. User changes to the table will be passed to the updateable ResultSet after validation.

I've looked a little bit at how sorting is done normally, but most implementations seems to rely on the JTable creating a javax.swing.RowSorter with a Comparator predicate, or on maintaining a sorted list of rows that fires events when changed. So, my questions:

ORM frameworks are NOT an answer to this question, because the data do not map well to entity objects. Also, the DBMS I am using is H2.

EDIT: Sortable JTable libraries based on applying Comparators or sorting predicates to row objects are also unsuitable, unfortunately. I do not believe I will be able to hold all objects in memory in order to perform sorting. This problem prevents me from using the SwingX JXTables, GlazedLists, or similar libraries. I wish I could, but I can't. Period.

** I will be dealing with many thousand rows, potentially millions, with numerous columns. Yes, I really DO need to use SQL to do the sorting and filtering.**

Questions: (in descending importance)

  1. How do I show indicators for which column is used to sort rows?
  2. How do I get the JTable to fire appropriate events when the column headers are LEFT-clicked to change sort order?
  3. Is there an easier way to force the JTable to update when the database changes?
  4. Is there a library that would make all this considerably easier (connecting DB queries or views and JTables)?
  5. Am I going to run into horrible, horrible problems when I design the system like this?

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

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

发布评论

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

评论(4

风月客 2024-07-28 08:08:50

我自己从未使用过它,但是JIDE Data Grids提供了一个DatabaseTableModel,它提供了过滤和排序功能支持使用 SQL WHERE 和 ORDER BY。

I have never used it myself but JIDE Data Grids provides a DatabaseTableModel that provides filtering and sorting support using SQL WHERE and ORDER BY.

她说她爱他 2024-07-28 08:08:50

在回答 1 和 2 时,请查看 SwingX,它已经包含一个内置的表类排序(和过滤)。 您也许能够适应这一点。

当我设计这样的系统时,我会遇到可怕的问题吗?

根据经验,是的。 我参与了一个与此几乎完全相同的项目,其中有人设计了一个 JTable,据说可以“神奇地”绑定到数据库表。 这将显示逻辑和数据库访问耦合在一起,形成了一个可怕的混乱,我们用反射驱动的表模型和单独的记录 CRUD 操作完全取代了它。

你说ORM不是答案...

  • 如果数据的格式没有改变,那么无论如何它都值得考虑。 您的“实体”类不需要代表现实世界的实体。

  • 如果(正如我怀疑的那样)您的实体格式发生变化,可能值得考虑:

    • 灵活的基于映射的 Record 类,它将记录存储为键值对;

    • 为您的显示逻辑动态构建的表模型,通过查询记录键构建,插入 SwingX 表中以免费进行排序和过滤;

    • 类似设计的Repository类,它独立于表本身封装数据库访问,负责加载和保存Record。 它充当可更新的 ResultSet 和视图之间的适配器(尽管我会检查以这种方式使用 ResultSet 是否需要在数据可见时打开数据库连接...)。

    这种“显示和排序记录的表格”和“管理数据的存储库”的分离意味着:

    • 您可以重复使用该表来存储非数据库绑定的数据;
    • 您可以在表格以外的其他内容中显示数据库绑定记录;
    • 你不会因为尝试构建和测试这个东西而发疯:)

In answer to 1 and 2, check out SwingX, which already includes a table class with built-in sorting (and filtering). You may be able to adapt this.

Am I going to run into horrible, horrible problems when I design the system like this?

From experience, yes. I worked on a project almost exactly the same as this, where someone had designed a JTable that supposedly 'magically' bound to a database table. This coupled display logic and database access together in one big horrible mess, which we replaced entirely with reflection-driven table models and separate record CRUD operations.

You say that ORM is not the answer...

  • If the format of the data doesn't change, then it's worth considering anyway. Your 'entity' classes need not represent real-world entities.

  • If (as I suspect) your entity format changes, it might be worth considering:

    • A flexible map-based Record class which stores records as key-value pairs;

    • Dynamically-built table models for your display logic, built by querying record keys, plugged into SwingX tables to get sort and filter for free;

    • A similarly-designed Repository class which encapsulates your database access separately from the table itself, responsible for loading and saving Records. This acts as an adapter between your updateable ResultSet and the view (although I'd check whether using a ResultSet this way is going to require an open database connection whilst data is visible...).

    This separation into 'a table that displays and sorts records' and 'a repository that manages the data' means:

    • You can reuse the table for non-database-bound data;
    • You can display database-bound records in things other than tables;
    • You won't go mad trying to build and test the thing :)
策马西风 2024-07-28 08:08:50

您应该能够子类化 javax.swing.RowSorter 以便创建在数据库中进行排序的行排序器。 从 API 文档来看:

“RowSorter 实现通常没有与底层模型的一对一映射,但它们可以。例如,如果数据库进行排序,toggleSortOrder 可能会调用数据库(在后台线程上),并重写映射方法以返回传入的参数。”

http://docs.oracle.com/javase/6/docs/api/javax/swing/RowSorter.html

You should be able to subclass javax.swing.RowSorter in order to create a row sorter that does the sorting in the database. From the API docs:

"RowSorter implementations typically don't have a one-to-one mapping with the underlying model, but they can. For example, if a database does the sorting, toggleSortOrder might call through to the database (on a background thread), and override the mapping methods to return the argument that is passed in."

http://docs.oracle.com/javase/6/docs/api/javax/swing/RowSorter.html

蓝天白云 2024-07-28 08:08:50

撇开数据库的东西不谈,有一个名为 SortableTable 的类,它是 JIDE 网格的一部分。 它在表头中用一点^或v显示排序,并且支持按1列以上排序(1v、2v等)。

替代文字

Leaving aside the database stuff there's a class called SortableTable that's a part of JIDE Grids. It displays the sorting with a little ^ or v in the table header, and supports sorting by more than 1 column (1v, 2v, etc.).

alt text

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