2010-07-26 26 views
11

Me gustaría que mi JTable utilice diferentes editores de celdas para diferentes celdas en una sola columna. Piense en una tabla de valor de etiqueta de dos columnas como:JTable - editores de varias celdas en una columna

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

¿Cómo puedo construir el editor dinámicamente? Algo así como un TableCellEditorFactory sería perfecto.

Respuesta

8

Tiene que implementar su propio editor de celda y asignarlo a la columna. Probablemente debería hacer lo mismo con un renderizador de celdas (por ejemplo, los booleanos se mostrarán como una casilla de verificación en lugar de "verdadero"/"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 es de SwingX

1

Llego a otra solución, ya que quería volver a utilizar los editores por defecto ... La siguiente clase redefine el getColumnClass para tener una respuesta diferente. Por lo que he probado, funciona bien, y puedo usar setDefaultEditor y demás. Puede observar que es posible mejorar este comportamiento para aplicarlo solo en las columnas deseadas.

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. Es posible ampliar JTable en lugar de JXTable.

Cuestiones relacionadas