What responsibilities fall with Java Swing's TableModel...
Who should present the formatted display to the user?
Is there any official guidance?
The help for getValueAt
states:
Returns the value for the cell at columnIndex and rowIndex.
There is no mention of formatting here. It returns "the value" for the cell. An Object
.
I have seen different implementations - even in products I have worked on. I feel there isn't much consistency.
TableModel
DecimalFormat decimalFormat = new DecimalFormat("#.###");
@Override
public Object getValueAt(int row, int column) {
...
decimalFormat.format(myObjectModel.GetFoo(row).getSomeDoubleProperty());
}
DefaultTableCellRenderer
public final class PositionDoubleCellRenderer extends DefaultTableCellRenderer {
private final String formatPattern = "%,.03f";
@Override
public Component getTableCellRendererComponent(
final JTable table, Object value, final boolean isSelected, final boolean hasFocus, final int row, final int column
) {
String formattedValue = "";
if (value instanceof Double) {
double numeric = (Double) value;
if (ConstantsModel.isConstant(numeric)) {
formattedValue = "";
} else {
formattedValue = String.format(formatPattern, numeric);
}
}
return super.getTableCellRendererComponent(table, formattedValue, isSelected, hasFocus, row, column);
}
}
There are pro's and con's depending on which mechanism you use. I don't know of any other ways to format off the top of my head, but I have had this thought on my mind for a while now.
Who should present the formatted display to the user?
The view. The JTable
uses renderers
to format/display the data.
in order to have consistent formatting of data in different tables for doubles, you then have to open up each table model and change for getValueAt
The data should not change. Therefore the getValueAt(...) method should not change.
A renderer can be shared by multiple tables.
You can even change the way the data is presented to the table by overriding the getColumnClass(...)
method of a JTable
.
The table has some default renderers for Boolean.class, Number.class, Icon.class etc.
So, for example if you have an Integer value stored in the model and if you override the getColumnClass(...)
method of the table to return:
Integer.class
- the data will be formatted as a number and displayed right alignedObject.cloass
- the data will be treated like a String and displayed left justified.Or you can even assign a custom renderer to a specific column in the TableColumnModel
. So if you wanted the Integer formatted as a "percentage" you can use a renderer for that.
So, bottom line is the same data can be displayed in an unlimited number of ways when the proper renderer is used.
Check out Table Format Renderers for an easy way to create reusable formatting renderers.