JTable
Custom cell renders
ditch the array and take a List of objects.
write a custom tablemodel using the http://jakarta.apache.org/commons/beanutils/ to wrap the model around your POJO/javabean
this is what I cooked up before I remembered the commons lib:
public class RecordListModel<E> extends AbstractTableModel {
protected List<E> list;
protected String[] fields;
private String[] collumNames;
private Method[] methodes;
public RecordListModel(List<E> list, String[] fields) {
this(list,fields,fields);
}
public RecordListModel(List<E> list, String[] fields, String[] collumNames) {
this.list = list;
this.fields = fields;
this.collumNames = collumNames;
methodes = new Method[fields.length];
if(fields.length!=collumNames.length)
throw new IllegalArgumentException("not the same amount of fields and collum names specified.");
}
public int getRowCount() {
return list.size();
}
public int getColumnCount() {
return fields.length;
}
public String getColumnName(int columnIndex) {
if(!(columnIndex<0) && !(columnIndex>collumNames.length))
return collumNames[columnIndex];
return super.getColumnName(columnIndex);
}
public Object getValueAt(int rowIndex, int columnIndex) {
Object value = null;
E object = list.get(rowIndex);
Method method = methodes[columnIndex];
if(method==null) {
method = getMethodFor(object.getClass(),fields[columnIndex]);
methodes[columnIndex] = method;
}
try {
value = method.invoke(object);
} catch (IllegalArgumentException e) {
throw new RuntimeException("problem with invoking methode; getters should not have parameters");
} catch (IllegalAccessException e) {
/* should not occour since getMethodFor class already throws the exception*/
throw new RuntimeException("field not accessable; make sure theres an public getter for the field");
} catch (InvocationTargetException e) {
throw new RuntimeException("Error invoking while invoking the getter; getter threw an exception");
}
return value;
}
private Method getMethodFor(Class<? extends Object> forClass, String field) {
try {
return forClass.getMethod("get"+field);
} catch (SecurityException e) {
throw new RuntimeException("field not accessable through getter; make sure theres an public getter for the field");
} catch (NoSuchMethodException e) {
throw new RuntimeException("(getter-)Methode unknown ('"+forClass.getName()+".get"+field+"()'), check your constructor call / make sure theres a getter for the field");
}
}
private Class<?> getPrimitiveWrapper(Class primitive) {
if(primitive.equals(short.class)) {
return Short.class;
} else if(primitive.equals(int.class)) {
return Integer.class;
} else if(primitive.equals(long.class)) {
return Long.class;
} else if(primitive.equals(float.class)) {
return Float.class;
} else if(primitive.equals(double.class)) {
return Double.class;
} else if(primitive.equals(boolean.class)) {
return Boolean.class;
} else if(primitive.equals(byte.class)) {
return Byte.class;
} else if(primitive.equals(char.class)) {
return Character.class;
}
return Object.class;
}
public List<E> getList() {
return list;
}
public void setList(List<E> list) {
this.list = list;
fireTableDataChanged();
}
@Override
public Class<?> getColumnClass(int columnIndex) {
if(list.isEmpty())
return super.getColumnClass(columnIndex);
Class forClass = getFieldClass(columnIndex);
// to avoid renderer getting nullpointerException because the super class of a primitive is non existent
if(forClass.isPrimitive())
return getPrimitiveWrapper(forClass);
return forClass;
}
protected Class getFieldClass(int numberField) {
Method method = methodes[numberField];
if(method==null) {
method = getMethodFor(list.get(0).getClass(),fields[numberField]);
methodes[numberField] = method;
}
return method.getReturnType();
}
}
srry about the lack of commented code.