【问题标题】:Unable to sort the JTable by Date无法按日期对 JTable 进行排序
【发布时间】:2014-11-13 12:03:16
【问题描述】:

我有一个 JTable,它的第一列是一个日期。然而,这实际上不是一个Date 对象,它是一个String,它以英国格式显示日期。下面是我的代码

private class DisplayAllRevenue extends ComponentAdapter
     {
         @Override
         public void componentShown(ComponentEvent e)
         {
             DefaultTableModel model = (DefaultTableModel) allRevenueTable.getModel();
             model.setRowCount(0);


             dbConnector = new DBHandler();
             dbConnector.makeConnection();

             java.sql.Date dateOfLastUpdate=null;


             ResultSet portfolioRs = dbConnector.selectAllDetails(getPortfolioData);

             try
             {
                 if(portfolioRs.isBeforeFirst()==false)
                 {
                     JOptionPane.showMessageDialog(null,"Empty");
                 }
                 else
                 {
                     while(portfolioRs.next())
                     {
                         String provider = portfolioRs.getString("Provider Name");
                         String client = portfolioRs.getString("Client Name");
                         int idPortfolio = portfolioRs.getInt("idPortfolio");
                         dateOfLastUpdate = portfolioRs.getDate("Update_Date");


                         String dateOfLastUpdateS = getDateInUKFormat(convertSQLDateToJavaDate(dateOfLastUpdate));

                         Object[]row3 = {dateOfLastUpdateS, provider, client, idPortfolio};

                         model.addRow(row3);
                         }

                     }

                    //Sort the Table
                    DefaultRowSorter sorter = ((DefaultRowSorter)allRevenueTable.getRowSorter()); 
                    ArrayList list = new ArrayList();
                    list.add( new RowSorter.SortKey(0, SortOrder.DESCENDING) );
                    sorter.setSortKeys(list);
                    sorter.sort();
                 }
             }
             catch(SQLException sql)
             {
                 JOptionPane.showMessageDialog(null,"Error displaying data");
                 sql.printStackTrace();
             }
             finally
             {
                 dbConnector.closeConnection();
             }
         }
     }

如您所见,我正在尝试按Date 对表格进行排序。但不幸的是,它没有奏效!一切都出了问题。我想知道这是因为Date 实际上是String

那么,如何根据日期“正确”按表格排序?

【问题讨论】:

  • 为了尽快获得更好的帮助,请发布MCVE(最小完整可验证示例)。硬编码一些数据来替换数据库。
  • @AndrewThompson:我正在使用 Netbeans GUI 构建器。因此,发布自动生成的代码将是一团糟!
  • 祝你好运。投票结束。
  • 将日期字符串解析为日期对象,或者更好地将它们作为日期对象从数据库中读取。将这些放入您的表格中,然后排序应该起作用。如果日期的出现看起来不合适,请创建一个单元格渲染器来自定义它。
  • @stefan:这就是我知道该怎么做的。

标签: java swing sorting user-interface jtable


【解决方案1】:

我想知道这是因为日期实际上是一个字符串。

是的,很有可能。请注意,您不必将表模型中包含的数据与其表示混合在一起。在这种情况下,您可以完美地拥有一个Date 对象并以英国格式或您喜欢的任何格式显示它。更好的是,对于国际化贸易,您可以让表格单元格渲染器/编辑器解析当前语言环境并相应地应用日期格式。

整个问题是通过覆盖getColumnClass(columnIndex) 方法在表模型实现中检索适当的类。如果我们这样做正确,那么JTable 组件将能够:

有关更好的解释,请参阅How to Use Tables 教程的Sorting and Filtering 部分。但简而言之:

要确定将哪个Comparator 用于列,TableRowSorter 尝试依次应用以下每个规则。规则是 按照下面列出的顺序进行;第一条规则提供 使用带有Comparator 的排序器,并忽略其余规则。

  1. 如果已通过调用 setComparator 指定了比较器,请使用该比较器。
  2. 如果表模型报告列数据由字符串组成(TableModel.getColumnClass 为此返回String.class 列),使用比较器根据当前字符串对字符串进行排序 语言环境。
  3. 如果TableModel.getColumnClass返回的列类实现Comparable,请使用比较器,根据 Comparable.compareTo 返回的值。
  4. 如果已通过调用 setStringConverter 为表指定了字符串转换器,请使用对结果字符串进行排序的比较器 基于当前语言环境的表示。
  5. 如果上述规则均不适用,请使用一个比较器,该比较器在列数据上调用toString,并根据以下规则对结果字符串进行排序 当前语言环境。

既然Date 类实现了Comparable 接口,那么它就是第3 点的情况。因此,再次正确地覆盖getColumnClass() 将引导您解决问题。


题外话

请注意,数据库调用是耗时的任务,可能会阻塞Event Dispatch Thread (EDT),导致 GUI 无响应。 EDT 是单一且特殊的 必须执行 Swing 组件创建和更新并进行事件处理的线程。

话虽如此,请看一下代码中的这一部分:

private class DisplayAllRevenue extends ComponentAdapter {
     @Override
     public void componentShown(ComponentEvent e) {
         // Event handling code: it is performed in the EDT
     }
}

如果您每次显示组件时都调用数据库,那么您将遇到严重的性能问题。您可以考虑添加一个按钮来让用户刷新表格的数据,而不是尝试在显示组件时自动执行此操作。

此外,为了避免阻塞 EDT,您可以考虑使用 SwingWorker 在后台线程中执行数据库调用并更新 EDT 中的 Swing 组件。在Concurrency in Swing trail 中查看更多信息。

【讨论】:

  • 我发现这是正确的方式。我试过了,但我遇到了一些问题。尽管我遇到了问题,但由于这个答案是正确的,我将其标记为已解决。请在这里看看我的新问题 - stackoverflow.com/questions/26924799/…
猜你喜欢
  • 1970-01-01
  • 2020-10-30
  • 2018-08-14
  • 2015-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多