I am encountering a problem with JTable. I searched this forum on JTable but could not find any answer. Please any Swing gurus take a look and give me a hand.
I create a JTable with instant validation requiring all inputs to be a decimal field. The table can be filled by keyboard input, it can also be filled by clicking a button ("Test" button), which gets the number from a database and fill in the table.
So far, my code works just fine when users type in the input. The table only accepts a double number. However, when the user clicks the button which gets the number from the database, a nasty exceptio occurs:
Exception occurred during event dispatching:
ang.IllegalArgumentException: Cannot format given Object as a Number
at java.text.NumberFormat.format(NumberFormat.java:204)
........
Here is the port of my code. It has been greatly simplified. When the user clicks "Test" button, the table is supposed to disply a number "3.3" at the cell (1,1), instead the it throws the nasty exception "Cannot format Object as a Number". Please note that as users type in the table, everything is just fine.
public class myPanel extends JPanel{
Object data[][];
String tableColumn[] = {"Item", "DoubleNumber"};
MyTableModel myModel;
JTable myTable;
JButon myButton;
MyPanel(){
data = new Object[2][2];
myModel = new MyTableModel(data, tableColumn);
myTable = new JTable(myModel);
setupDecimalEditor(myTable);
myButton = new JButton("Test");
myButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae){
myModel.setValueAt(Double.toString(3.3), 1,1);}
});
add(myTable);
add(myButton);
}
class MyTableModel extends AbstractTableModel{
Object data[][];
String columnName[];
MyTableModel(Object tableData[][], String tableColumn[]){
data = tableData;
columnName = tableColumn;
}
public int getColumnCount(){
return columnName.length;
}
public int getRowCount(){
return data.length;
}
public String getColumnName(int col){
return columnName[col];
}
public Object getValueAt(int row, int column){
return data[row][column];
}
public Class getColumnClass(int c){
return Double.class }
public boolean isCellEditable(int row, int column){
if(column == 0)
return false;
else
return true;
}
public void setValueAt(Object value, int row, int col){
data[row][col] = value;
fireTableCellUpdated(row, col);
}
}
public void setupDecimalEditor(JTable myTable){
final DecimalField decimalField = new DecimalField(0, 10);
decimalField.setHorizontalAlignment(DecimalField.CENTER);
DefaultCellEditor decimalEditor = new DefaultCellEditor(decimalField){
public Object getCellEditorValue(){
return new Double(decimalField.getValue());
}
};
table.setDefaultEditor(Double.class, decimalEditor);
}
}
THE DecimalField is contained in a separate file as follow:
public class DecimalField extends JTextField {
private NumberFormat format;
//DecimalFormat format;
/** Creates new DecimalField */
public DecimalField(double value, int column) {
super(column);
//setDocument(new FormattedDocument(f));
format = (DecimalFormat)NumberFormat.getNumberInstance(Locale.US);
setValue(value);
}
public double getValue(){
double dReturn = 0.0;
try{
dReturn = format.parse(getText()).doubleValue();
}catch(ParseException ex){
Toolkit.getDefaultToolkit().beep();
}
return dReturn;
}
public void setValue(double value){
setText(format.format(value));
}
protected Document createDefaultModel(){
//return new FormattedDocument(format);
return new DecimalDocument();
}
protected class DecimalDocument extends PlainDocument {
public void insertString(int offs, String str, AttributeSet a) throws BadLocationException{
String currentText = getText(0, getLength());
String beforeOffset = currentText.substring(0, offs);
String afterOffset = currentText.substring(offs, currentText.length());
String proposedResult = beforeOffset + str + afterOffset;
try{
format.parseObject(proposedResult);
super.insertString(offs, str, a);
}catch(ParseException ex){
Toolkit.getDefaultToolkit().beep();
System.out.println("Am I lying: proposedResult = " + proposedResult);
System.out.println("insertString: could not parse: " + proposedResult);
}
/*
catch(NumberFormatException ex){
Toolkit.getDefaultToolkit().beep();
System.err.println("insertString: could not parse: " + proposedResult);
//remove(0, getLength());
}
System.out.println("DecimentDocument->End of insert");
*/
}
public void remove(int offs, int len) throws BadLocationException{
String currentText = getText(0, getLength());
String beforeOffset = currentText.substring(0, offs);
String afterOffset = currentText.substring(len+offs, currentText.length());
String proposedResult = beforeOffset + afterOffset;
try{
if(proposedResult.length() !=0)
format.parseObject(proposedResult);
super.remove(offs, len);
} catch(ParseException ex){
Toolkit.getDefaultToolkit().beep();
System.err.println("remove: could not parse: " + proposedResult);
}
}
}
}