无法按日期对JTable排序 [英] Unable to sort the JTable by Date

查看:97
本文介绍了无法按日期对JTable排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a JTable, where the first column of it is a Date. However, this is not actually a Date object, it is a String which display the date in UK format. Below is my code

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.

As you can see, I am trying to sort the table by the Date. But unfortunately, it didn't work! Everything just went out of order. I am wondering this because the Date is actually a String.

那么,如何根据日期对表进行正确"排序?

So, how can I sort by table "correctly" according to the Date ?

推荐答案

我想知道这是因为Date实际上是一个字符串.

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

Yes, most likely. Note that you don't have to mix the data contained in the table model with its representation. In this case you could perfectly have a Date object and show it in UK format or whatever format you like. Even better, for internationalization trade you could let the table cell renderer/editor resolve the current locale and apply a date format accordingly.

整个问题涉及通过覆盖

The whole matter is about retrieving the appropriate class in the table model implementation by overriding getColumnClass(columnIndex) method. If we do this correctly, then JTable component will be able to:

有关更好的说明,请参见排序和过滤 如何使用表教程的部分"部分.概括地说:

For a better explanation see Sorting and Filtering section of How to Use Tables tutorial. But in a nutshell:

要确定要对列使用哪个Comparator,请TableRowSorter 尝试依次应用以下每个规则.规则是 按照下面列出的顺序;提供以下内容的第一条规则 使用带有Comparator的分选器,其余规则将被忽略.

To determine which Comparator to use for a column, TableRowSorter attempts to apply each of the following rules in turn. Rules are followed in the order listed below; the first rule that provides the sorter with a Comparator is used, and the remainining rules ignored.

  1. 如果通过调用setComparator指定了比较器,请使用该比较器.
  2. 如果表模型报告列数据由字符串组成(T ableModel.getColumnClass为此返回String.class 列),使用比较器根据当前字符串对字符串进行排序 语言环境.
  3. 如果TableModel.getColumnClass返回的列类实现了Comparable,请使用比较器对字符串进行排序,该比较器基于 Comparable.compareTo返回的值.
  4. 如果通过调用setStringConverter为表指定了字符串转换器,请使用比较器对结果字符串进行排序 基于当前语言环境的表示形式.
  5. 如果没有前面的规则适用,请使用比较器,该比较器对列数据调用toString,并根据以下条件对结果字符串进行排序 当前语言环境.
  1. If a comparator has been specified by invoking setComparator, use that comparator.
  2. If the table model reports that the column data consists of strings (TableModel.getColumnClass returns String.class for that column), use a comparator that sorts the strings based on the current locale.
  3. If the column class returned by TableModel.getColumnClass implements Comparable, use a comparator that sorts the strings based on the values returned by Comparable.compareTo.
  4. If a string convertor has been specified for the table by invoking setStringConverter, use a comparator that sorts the resulting string representations based on the current locale.
  5. If none of the previous rules apply, use a comparator that invokes toString on the column data and sorts the resulting strings based on the current locale.

由于Date类实现了Comparable接口,所以这是第3点的情况.因此,再次正确地重写getColumnClass()会导致您解决问题.

Since Date class implements Comparable interface, then it's a case of point 3. So, once again, overriding getColumnClass() correctly will lead you to solve your problem.

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

Please note database calls are time consuming tasks and may block the Event Dispatch Thread (EDT) causing the GUI become unresponsive. The EDT is a single and special thread where Swing components creation and update must be performed and event handling take place.

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

Having said that, take a look to this part in your code:

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

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

If you make database calls every time the component is shown then you'll have severe performance issues. You might consider add a button to let the users refresh the table's data instead of trying to do that automatically when the component is shown.

此外,为了避免阻止EDT,您可以考虑使用 SwingWorker 在后台线程中执行数据库调用并更新EDT中的Swing组件.有关更多信息,请参见 Swing跟踪中的并发性.

Additionally, in order to avoid blocking the EDT you might consider use a SwingWorker to perform database calls in a background thread and update Swing components in the EDT. See more in Concurrency in Swing trail.

这篇关于无法按日期对JTable排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆