2014-11-14 13 views
5

Si prega di dare un'occhiata al codice qui sottoordinamento non valido alla data in 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); 
    } 
} 

Ora, basta provare a risolverlo utilizzando il campo Date. Lo sta smistando in modo non valido! Di seguito è il risultato!

enter image description here

perché questo sta accadendo in questo modo? Ho anche usato cell render!

risposta

4

@ Sniper non un answert, ma non riesco a resistere, perché il codice è molto complicato, sbagliato progettato, manca lì lighweight necessario per ...

L'elemento chiave che manca è la forzatura dei TableModel. getColumnClass(), questo è essenziale per la tavola smistamento operato

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

Grazie. Apprezzo la risposta. –

+0

@Sniper sei il benvenuto – mKorbel

5

La tabella non sa che la colonna contiene sempre le istanze di data e che deve dunque sorta in ordine cronologico, a meno che non si dà queste informazioni, sovrascrivendo il metodo getColumnClass() del modello da tavolo:

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

aggiuntive bonus: le colonne numeriche e booleane verranno automaticamente renderizzate e ordinate correttamente.

+0

Grazie per la risposta. In quale posto dovrei inserire il tuo codice? –

+0

e, non sono chiaro riguardo al codice, la mente fornisce un esempio completo e funzionale per favore? –

+0

@munyul: l'ho già fatto e ho impostato il modello senza parametri. Ma è semplicemente dando 'ArrayIndexOutOfBounds Exception' –

2

Ecco la risposta, utilizzando il codice da 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); 

Questo codice viene inserito nel costruttore, sostituendo le prime poche righe in esso contenute.