2010-07-26 51 views
11

我希望我的JTable在一列中爲不同的單元格使用不同的單元格編輯器。想想兩列標籤值表:JTable - 一列中的多個單元格編輯器

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

我該如何動態構建編輯器?像TableCellEditorFactory這樣的東西將是完美的。

回答

8

你必須實現自己的單元格編輯器並將其分配給列。您應該對單元格渲染器執行相同的操作(例如,布爾值將顯示爲複選框而不是「true」/「false」)。

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

注: DatePickerCellEditor來自SwingX

1

我來到另一個解決方案,因爲我想重用默認編輯器...下面的類重新定義getColumnClass以得到不同的答案。據我測試,它工作正常,我可以使用setDefaultEditor等。您可以注意到,可以增強此行爲以將其僅應用於期望的列。

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

}

注:可以擴展JTable而不是JXTable

相關問題