I'm creating a TableModel
which extends AbstractTableModel
. Its contents, though, changes regularly and the number of columns changes depending on the data displayed. Occasionally, I'll need to use a ComboBox
to edit the cells in column 2, and occasionally I'll need a ComboBox
for cells in column 3.
I know you can set the default renderer of a table by doing table.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor(myComboBox));
Can I set the CellEditor
within my TableModel
dynamically, so that the CellEditor
is updated when I call table.updateUI()
?
Edit: I'm basically passing my TableModel
a big WellCollection
data structure that I'm using. At risk of boring you with details, it consists of Wells
, which consist of Attributes
, which consist of ProposedValues
. That's not too important, though. The important part is that I want users to be able to flip through attributes and have different ProposedValues
display in the table when they click next (which I previously accomplished with updateUI()
).
Note that an Attribute
can either be an elevation type or not an elevation type. If it is an elevation type, there needs to be an extra column in there.
Here's my code:
public class ProposedValueTableModel extends AbstractTableModel{
private WellCollection wells;
public ProposedValueTableModel(WellCollection wells){
this.wells = wells;
}
@Override
public int getColumnCount() {
// if we're dealing with elevation values, we want fields for the value, the elevation type,
// the source, and additional comments. If not, only show value, source, and comments.
if(wells.getCurrAttribute().isElevationType())
return 4;
else return 3;
}
@Override
public int getRowCount() {
//NOTE: add 1 for extra, blank row!
return wells.getCurrAttribute().getProposedValues().size()+1;
}
@Override
public Object getValueAt(int row, int col) {
//TODO: convert this to handy dandy switch statements
// make the last row blank to allow entries
if (row==wells.getCurrAttribute().getProposedValues().size())
return "";
ProposedValue propVal = wells.getCurrAttribute().getProposedValues().get(row);
//if we're NOT dealing with an elevation type, simply have three fields
if(wells.getCurrAttribute().isElevationType()==false){
switch(col){
case 0:
return propVal.val;
case 1:
return propVal.source;
case 2:
return propVal.comment;
}
}
// if it IS an elevation value, include elevation type
else{
switch(col){
case 0:
return propVal.val;
case 1:
return propVal.elevType;
case 2:
return propVal.source;
case 3:
return propVal.comment;
}
}
return "";
}
public String getColumnName(int col){
if(wells.getCurrAttribute().isElevationType() ==false){
switch(col){
case 0:
return "Proposed value";
case 1:
return "Source";
case 2:
return "Comment";
}
}
else{
switch(col){
case 0:
return "Proposed value";
case 1:
return "Type";
case 2:
return "Source";
case 3:
return "Comment";
}
}
return "header";
}
public boolean isCellEditable(int row, int col){
return true;
}
public void setValueAt(Object value, int row, int col){
// we're adding something to the last row, then add a new ProposedValue to the proposedValues array
if(row == wells.getCurrAttribute().getProposedValues().size()){
wells.getCurrAttribute().getProposedValues().add(new ProposedValue());
}
ProposedValue propVal = wells.getCurrAttribute().getProposedValues().get(row);
if(wells.getCurrAttribute().isElevationType()==false){
switch(col){
case 0:
// Value
propVal.val = (String)value; break;
case 1:
// Source
propVal.source = (String)value; break;
case 2:
// Comment
propVal.comment = (String)value; break;
}
}
else{
switch(col){
case 0:
// Value
propVal.val = (String)value; break;
case 1:
// Elevation type
propVal.elevType = (String)value; break;
case 2:
// Source
propVal.source = (String)value; break;
case 3:
// Comment
propVal.comment = (String)value; break;
}
}
//TODO: find out why this is necessary
fireTableCellUpdated(row, col);
}
}