无法按日期对JTable排序 [英] Unable to sort the JTable by Date
问题描述
我有一个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 aComparator
is used, and the remainining rules ignored.
- 如果通过调用
setComparator
指定了比较器,请使用该比较器. - 如果表模型报告列数据由字符串组成(T
ableModel.getColumnClass
为此返回String.class
列),使用比较器根据当前字符串对字符串进行排序 语言环境. - 如果
TableModel.getColumnClass
返回的列类实现了Comparable
,请使用比较器对字符串进行排序,该比较器基于Comparable.compareTo
返回的值. - 如果通过调用
setStringConverter
为表指定了字符串转换器,请使用比较器对结果字符串进行排序 基于当前语言环境的表示形式. - 如果没有前面的规则适用,请使用比较器,该比较器对列数据调用
toString
,并根据以下条件对结果字符串进行排序 当前语言环境.
- If a comparator has been specified by invoking
setComparator
, use that comparator. - If the table model reports that the column data consists of strings (T
ableModel.getColumnClass
returnsString.class
for that column), use a comparator that sorts the strings based on the current locale. - If the column class returned by
TableModel.getColumnClass
implementsComparable
, use a comparator that sorts the strings based on the values returned byComparable.compareTo
. - 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. - 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屋!