This week's book giveaway is in the Jython/Python forum.
We're giving away four copies of Murach's Python Programming and have Michael Urban and Joel Murach on-line!
See this thread for details.
Win a copy of Murach's Python Programming this week in the Jython/Python forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Help: JTable with data validation  RSS feed

 
Sam Zheng
Ranch Hand
Posts: 61
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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);
}
}
}
}
 
Tim Troy
Ranch Hand
Posts: 51
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You might have to tell the table that you are done editing. If the cell was still selected, the editor was still active.
 
Sam Zheng
Ranch Hand
Posts: 61
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It seems none of you Swing Gurus have reviewed my dirty code above. In fact, this is an interesting problem. Again, the program works fine in accepting user input. The problem is in setting the value on the table within the program by clicking the "Test" button. I found out that if I set all fields on the table model as Object or String, it doesn't have any problem either. The problem occurs only when I set the column as anyting other than Object and String, such as Double, Integer.
Any suggestions are appreciated!
Sam
 
Paul Stevens
Ranch Hand
Posts: 2823
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
myModel.setValueAt(Double.toString(3.3), 1,1);}
That is not a Double it is String. Try:
myModel.setValueAt(new Double(3.3), 1,1);}
 
Sam Zheng
Ranch Hand
Posts: 61
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul,
You are incredible! It works! What was I thinking :-)
Thanks!
Sam
[ June 27, 2003: Message edited by: Sam Zheng ]
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!