请查看以下代码
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
字段对其进行排序。它以无效的方式排序!结果如下!
为什么会这样发生?我甚至使用过cell render
!
答案 0 :(得分:6)
该表并不知道该列总是包含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);
额外奖励:数字和布尔列将自动呈现并正确排序。
答案 1 :(得分:5)
@Sciper不是一个回答,但我无法抗拒,因为你的代码非常复杂,设计错误,错过了轻量级所需... ...
缺少的关键元素是覆盖TableModel.getColumnClass(),这对于表格排序功能至关重要
import java.awt.*;
import java.text.DateFormat;
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 static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.table.*;
public class TableBasic {
private JFrame frame = new JFrame();
private String[] columnNames = {"Date", "String", "Long", "Boolean"};
private Object[][] data = {
{getJavaDate("13-11-2020"), "A", new Double(1), Boolean.TRUE},
{getJavaDate("13-11-2018"), "B", new Double(2), Boolean.FALSE},
{getJavaDate("12-11-2015"), "C", new Double(9), Boolean.TRUE},
{getJavaDate("12-11-2015"), "D", new Double(4), Boolean.FALSE}
};
private DefaultTableModel model = new DefaultTableModel(data, columnNames) {
@Override
public Class<?> getColumnClass(int column) {
return getValueAt(0, column).getClass();
}
};
private JTable table = new JTable(model);
private JScrollPane scrollPane = new JScrollPane(table);
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("dd/MM/yyyy");
public TableBasic() {
table.setPreferredScrollableViewportSize(table.getPreferredSize());
table.setAutoCreateRowSorter(true);
setRenderers();
// DefaultRowSorter has the sort() method
table.getRowSorter().toggleSortOrder(0);
frame.add(scrollPane);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void setRenderers() {
//TableColumnModel m = table.getColumnModel();
//"Integer", "String", "Interger", "Double", "Boolean", "Double", "String", "Boolean", "Date"
table.setDefaultRenderer(Date.class, new DateRenderer());
}
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) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
TableBasic frame = new TableBasic();
}
});
}
private class DateRenderer extends DefaultTableCellRenderer {
private static final long serialVersionUID = 1L;
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (!(value instanceof Date)) {
return this;
}
setText(DATE_FORMAT.format((Date) value));
return this;
}
}
}
答案 2 :(得分:2)
以下是使用JB Nizet的代码
的答案 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);
此代码进入构造函数,替换其中的前几行。