2010-07-26 16 views
11

Desidero che il mio JTable utilizzi diversi editor di celle per celle diverse in una singola colonna. Pensa a una tabella di valori delle etichette a due colonne come:JTable - editor di più celle in una colonna

Name   | Value 
--------------+-------------------------------- 
Identifier | ST33442 (string editor) 
Purchase Date | 7/7/10 (custom calendar editor) 
Status  | Broken (combo editor) 

Come posso creare l'editor in modo dinamico? Qualcosa come un TableCellEditorFactory sarebbe perfetto.

risposta

8

Devi implementare il tuo editor di celle e assegnarlo alla colonna. Probabilmente dovresti fare lo stesso con un renderer di celle (quindi, ad esempio, i booleani saranno resi come una casella di controllo invece di "vero"/"falso").

public class TableEditorTest { 

    public static void main(String[] args) { 
     Object[][] data = new Object[][] {{"Identifier", "ST33442"}, {"Purchase Date", new Date()}, {"Status", Boolean.FALSE}}; 
     String[] columnNames = new String[] {"Name", "Value"}; 
     TableModel model = new DefaultTableModel(data, columnNames); 
     JTable table = new JTable(model); 
     JScrollPane scrollPane = new JScrollPane(table); 
     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(scrollPane); 
     frame.pack(); 
     frame.setVisible(true); 

     table.getColumnModel().getColumn(1).setCellEditor(new CustomTableCellEditor()); 
    } 

    public static class CustomTableCellEditor extends AbstractCellEditor implements TableCellEditor { 
     private TableCellEditor editor; 

     @Override 
     public Object getCellEditorValue() { 
      if (editor != null) { 
       return editor.getCellEditorValue(); 
      } 

      return null; 
     } 

     @Override 
     public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { 
      if (value instanceof Date) { 
       editor = new DatePickerCellEditor(); 
      } else if (value instanceof String) { 
       editor = new DefaultCellEditor(new JTextField()); 
      } else if (value instanceof Boolean) { 
       editor = new DefaultCellEditor(new JCheckBox()); 
      } 

      return editor.getTableCellEditorComponent(table, value, isSelected, row, column); 
     } 
    } 
} 

N.B. DatePickerCellEditor da SwingX

1

Vengo a un'altra soluzione, poiché volevo riutilizzare gli editor predefiniti ... La seguente classe ridefinisce getColumnClass per avere una risposta diversa. Per quanto ho provato, funziona bene, e posso usare setDefaultEditor e così via. È possibile notare che è possibile migliorare questo comportamento per applicarlo solo sulle colonne desiderate.

public class JXMultiTypeColumnTable extends JXTable { 

private Map<Integer, Class<?>> viewedClassByColumn = new HashMap<Integer, Class<?>>(); 

public JXMultiTypeColumnTable(Object[][] rowData, Object[] columnNames) { 
    super(rowData, columnNames); 
} 

public JXMultiTypeColumnTable(int numRows, int numColumns) { 
    super(numRows, numColumns); 
} 

public JXMultiTypeColumnTable(TableModel dm, TableColumnModel cm, ListSelectionModel sm) { 
    super(dm, cm, sm); 
} 

public JXMultiTypeColumnTable(TableModel dm, TableColumnModel cm) { 
    super(dm, cm); 
} 

public JXMultiTypeColumnTable(TableModel dm) { 
    super(dm); 
} 

public JXMultiTypeColumnTable() { 
} 

@Override 
public Class<?> getColumnClass(int column) { 
    Class<?> recordedClass = this.viewedClassByColumn.get(column); 
    if (recordedClass != null) { 
     return recordedClass; 
    } 
    return super.getColumnClass(column); 
} 

private void recordViewedClass(int row, int column) { 
    this.viewedClassByColumn.put(column, 
      this.getModel().getValueAt(
      this.convertRowIndexToModel(row), this.convertColumnIndexToModel(column)) 
      .getClass()); 
} 

@Override 
public TableCellRenderer getCellRenderer(int row, int column) { 
    this.recordViewedClass(row, column); 
    return super.getCellRenderer(row, column); 
} 

@Override 
public TableCellEditor getCellEditor(int row, int column) { 
    this.recordViewedClass(row, column); 
    return super.getCellEditor(row, column); 
} 

}

N.B. È possibile estendere JTable anziché JXTable.

Problemi correlati