Java JTable中的日期排序无效

Java JTable中的日期排序无效,java,swing,sorting,date,jtable,Java,Swing,Sorting,Date,Jtable,请看下面的代码 import java.awt.*; import java.awt.event.*; import java.text.NumberFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; import javax.s

请看下面的代码

import java.awt.*;
import java.awt.event.*;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.table.*;

public class TableBasic extends JFrame
{
    public TableBasic()
    {

        String[] columnNames = {"Date", "String", "Long", "Boolean"};
        Object[][] data =
        {
            {getJavaDate("13-11-2020"), "A", new Long(1), Boolean.TRUE },
            {getJavaDate("13-11-2018"), "B", new Long(2), Boolean.FALSE},
            {getJavaDate("12-11-2015"), "C", new Long(9), Boolean.TRUE },
            {getJavaDate("12-11-2015"), "D", new Long(4), Boolean.FALSE}
        };

        final JTable table = new JTable(data, columnNames);
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        table.setAutoCreateRowSorter(true);
        table.getColumnModel().getColumn(0).setCellRenderer(tableCellRenderer);

        // DefaultRowSorter has the sort() method
        DefaultRowSorter sorter = ((DefaultRowSorter)table.getRowSorter()); 
        ArrayList list = new ArrayList();
        list.add( new RowSorter.SortKey(0, SortOrder.DESCENDING) );
        sorter.setSortKeys(list);
        sorter.sort();

        JScrollPane scrollPane = new JScrollPane( table );
        getContentPane().add( scrollPane );
    }

    private TableCellRenderer tableCellRenderer = new DefaultTableCellRenderer() 
    {

        SimpleDateFormat f = new SimpleDateFormat("dd-MM-yyyy");

        public Component getTableCellRendererComponent(JTable table,Object value, boolean isSelected, boolean hasFocus,int row, int column) 
        {
            if( value instanceof Date) 
            {
                value = f.format(value);
            }
            return super.getTableCellRendererComponent(table, value, isSelected,hasFocus, row, column);
        }
    };

    private Date getJavaDate(String s)
    {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
            Date d = sdf.parse(s);
             return d;

        } catch (ParseException ex) {
            Logger.getLogger(TableBasic.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }



    public static void main(String[] args)
    {
        TableBasic frame = new TableBasic();
        frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
    }
}
现在,只需尝试使用
Date
字段对其进行排序。这是一种无效的排序方式!下面是结果


为什么会这样?我甚至使用了
单元渲染

表不知道列始终包含日期实例,因此必须按时间顺序排序,除非您通过重写表模型的
getColumnClass()
方法为其提供该信息:

final Class<?>[] columnClasses = new Class<?>[] {Date.class, String.class, Long.class, Boolean.class};

DefaultTableModel model = new DefaultTableModel(...) {
    @Override
    public Class<?> getColumnClass(int column) {
        return columnClasses[column];
    }
});
JTable table = new JTable(model);
final Class[]columnClasses=新类[]{Date.Class,String.Class,Long.Class,Boolean.Class};
DefaultTableModel=新的DefaultTableModel(…){
@凌驾
公共类getColumnClass(int列){
返回columnClasses[列];
}
});
JTable table=新的JTable(模型);

额外的好处:数字列和布尔列将自动呈现并正确排序。

@Sniper不是答案,但我无法抗拒,因为您的代码非常复杂,设计错误,没有达到

缺少的关键元素是TableModel.getColumnClass()的重写,这对于表排序的正常运行至关重要

import java.awt.*;
导入java.text.DateFormat;
导入java.text.ParseException;
导入java.text.simpleDataFormat;
导入java.util.*;
导入java.util.logging.Level;
导入java.util.logging.Logger;
导入javax.swing.*;
在关闭时导入静态javax.swing.JFrame.EXIT_;
导入javax.swing.table.*;
公共类TableBasic{
私有JFrame=新JFrame();
私有字符串[]columnNames={“日期”、“字符串”、“长”、“布尔值”};
私有对象[][]数据={
{getJavaDate(“13-11-2020”),“A”,新的双精度(1),Boolean.TRUE},
{getJavaDate(“13-11-2018”),“B”,新的双精度(2),Boolean.FALSE},
{getJavaDate(“12-11-2015”),“C”,新的双精度(9),Boolean.TRUE},
{getJavaDate(“12-11-2015”),“D”,新的双精度(4),布尔值。FALSE}
};
private DefaultTableModel=新的DefaultTableModel(数据、列名){
@凌驾
公共类getColumnClass(int列){
返回getValueAt(0,列).getClass();
}
};
专用JTable表=新JTable(模型);
私有JScrollPane scrollPane=新JScrollPane(表);
私有静态最终日期格式日期\格式=新的SimpleDataFormat(“dd/MM/yyyy”);
公共表格基础(){
table.setPreferredScrollableViewportSize(table.getPreferredSize());
表.setAutoCreateRowSorter(真);
setRenders();
//DefaultRowSorter具有sort()方法
table.getRowSorter().toggleSortOrder(0);
frame.add(滚动窗格);
frame.setDefaultCloseOperation(关闭时退出);
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
私有void setrenders(){
//TableColumnModel m=table.getColumnModel();
//“整数”、“字符串”、“整数”、“双精度”、“布尔值”、“双精度”、“字符串”、“布尔值”、“日期”
table.setDefaultRenderer(Date.class,new DateRenderer());
}
私有日期getJavaDate(字符串s){
试一试{
SimpleDataFormat sdf=新的SimpleDataFormat(“dd-MM-yyyy”);
日期d=sdf.parse(s);
返回d;
}捕获(解析异常){
Logger.getLogger(TableBasic.class.getName()).log(Level.SEVERE,null,ex);
返回null;
}
}
公共静态void main(字符串[]args){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
TableBasic框架=新的TableBasic();
}
});
}
私有类DateRenderer扩展了DefaultTableCellRenderer{
私有静态最终长serialVersionUID=1L;
@凌驾
公共组件GetTableCellRenderComponent(JTable表、对象值、布尔isSelected、布尔hasFocus、int行、int列){
getTableCellRenderComponent(表、值、isSelected、hasFocus、行、列);
如果(!(日期的值实例)){
归还这个;
}
setText(DATE_FORMAT.FORMAT((DATE)value));
归还这个;
}
}
}

以下是答案,使用JB T中的代码

    String[] columnNames = {"Date", "String", "Long", "Boolean"};
    Object[][] data =
    {
        {getJavaDate("13-11-2020"), "A", new Long(1), Boolean.TRUE },
        {getJavaDate("13-11-2018"), "B", new Long(2), Boolean.FALSE},
        {getJavaDate("12-11-2015"), "C", new Long(9), Boolean.TRUE },
        {getJavaDate("12-11-2015"), "D", new Long(4), Boolean.FALSE}
    };

    final Class<?>[] columnClasses = new Class<?>[] {Date.class, String.class, Long.class, Boolean.class};

    DefaultTableModel model = new DefaultTableModel() {
        @Override
        public Class<?> getColumnClass(int column) {
            return columnClasses[column];
        }
    };
    model.setDataVector(data, columnNames);

    final JTable table = new JTable(model);
String[]columnNames={“日期”、“字符串”、“长”、“布尔值”};
对象[][]数据=
{
{getJavaDate(“13-11-2020”),“A”,新的Long(1),Boolean.TRUE},
{getJavaDate(“13-11-2018”),“B”,新Long(2),Boolean.FALSE},
{getJavaDate(“12-11-2015”),“C”,新Long(9),Boolean.TRUE},
{getJavaDate(“12-11-2015”),“D”,新的Long(4),Boolean.FALSE}
};
最终类[]columnClasses=新类[]{Date.Class,String.Class,Long.Class,Boolean.Class};
DefaultTableModel=新的DefaultTableModel(){
@凌驾
公共类getColumnClass(int列){
返回columnClasses[列];
}
};
model.setDataVector(数据、列名称);
最终JTable表格=新JTable(模型);

此代码进入构造函数,替换其中的前几行。

感谢您的回复。我应该把你的代码放在哪个地方?而且,我不清楚代码,请提供一个完整可行的例子好吗?@munyul:我已经做了,设置了没有参数的模型。但它只是给出了
ArrayIndexOutOfBounds异常
谢谢。我很感激你的回答。
    String[] columnNames = {"Date", "String", "Long", "Boolean"};
    Object[][] data =
    {
        {getJavaDate("13-11-2020"), "A", new Long(1), Boolean.TRUE },
        {getJavaDate("13-11-2018"), "B", new Long(2), Boolean.FALSE},
        {getJavaDate("12-11-2015"), "C", new Long(9), Boolean.TRUE },
        {getJavaDate("12-11-2015"), "D", new Long(4), Boolean.FALSE}
    };

    final Class<?>[] columnClasses = new Class<?>[] {Date.class, String.class, Long.class, Boolean.class};

    DefaultTableModel model = new DefaultTableModel() {
        @Override
        public Class<?> getColumnClass(int column) {
            return columnClasses[column];
        }
    };
    model.setDataVector(data, columnNames);

    final JTable table = new JTable(model);