2014-11-14 35 views
5

日期排序無效,請看看下面的代碼在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.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字段排序。它以無效的方式對它進行排序!以下是結果!

enter image description here

爲什麼發生這種情況也是這樣嗎?我甚至用過cell render

回答

4

@狙擊手不是answert,但我無法抗拒,因爲你的代碼是非常複雜的,錯誤的設計,錯過需要有lighweight爲...

缺少的關鍵因素是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; 
     } 
    } 
} 
+0

謝謝。我很欣賞答案。 –

+0

@Sniper你很受歡迎 – mKorbel

5

表不知道列總是包含日期實例,它因此必須按時間順序排序,除非你給它的信息,通過覆蓋表模型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); 

附加獎勵:數字和布爾列將自動呈現並正確排序。

+0

感謝您的回覆。我應該在哪個地方放置你的代碼? –

+0

,我不清楚代碼,Mind提供了一個完整的可行示例嗎? –

+0

@munyul:我已經完成了它,並且設置了沒有參數的模型。但它只是給'ArrayIndexOutOfBounds異常' –

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); 

此代碼進入您的構造函數,替換它的前幾行。